1

I am trying to load three separate tables from SQL Server 2012 into Oracle. I have established connections to SQL Server and Oracle in separate classes as seen below:

SQL Server connection:

public class TestSqlUtil {
    public Connection getConnection() throws SQLException, IOException
    {
        String propsFile = "tasmania.properties";
        Properties props = new Properties();
        InputStream inputStream = 
            this.getClass().getClassLoader().getResourceAsStream(propsFile);

        if (inputStream == null)
        {
            throw new FileNotFoundException("property file '" + propsFile
                + "' not found in the classpath");
        }

        props.load(inputStream);

        String dblogin = props.getProperty("sqlfdb.LOGIN");
        String dbpasswd = props.getProperty("sqlfdb.PASSWD");
        String jdbcDrv = props.getProperty("sqlfdb.JDBCOCIDRV");
        DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
        Connection con = DriverManager.getConnection(jdbcDrv, dblogin, dbpasswd);
        System.out.printf("successfull connection");
        System.out.println();
        return con;
    }
    public void cleanUp(Connection con, PreparedStatement ps, ResultSet rs)
        throws SQLException
    {
        if (rs != null) rs.close();
        if (ps != null) ps.close();
        if (con != null) con.close();
    }
    public static void main(String a[]) throws SQLException, IOException
    {
        DaoUtil tasmaniaUtil = new DaoUtil();
        tasmaniaUtil.getConnection();
    }
}

Oracle connection:

public class DaoUtil
{
    public Connection getConnection() throws SQLException, IOException 
    {
        String propsFile = "tasmania.properties";
        Properties props = new Properties();
        InputStream inputStream = 
            this.getClass().getClassLoader().getResourceAsStream(propsFile);

        if (inputStream == null)
        {
            throw new FileNotFoundException("property file '" + propsFile
                + "' not found in the classpath");
        }

        props.load(inputStream);

        String dblogin = props.getProperty("intfdb.LOGIN");
        String dbpasswd = props.getProperty("intfdb.PASSWD");
        String jdbcDrv = props.getProperty("intfdb.JDBCOCIDRV");
        DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
        Connection con = DriverManager.getConnection(jdbcDrv, dblogin, dbpasswd);
        System.out.printf("successfull connection");
        System.out.println();
        return con;
    }
    public void cleanUp(Connection con, PreparedStatement ps, ResultSet rs)
        throws SQLException 
    {
        if (rs != null) rs.close();
        if (ps != null) ps.close();
        if (con != null) con.close();
    }

    public static void main(String a[]) throws SQLException, IOException
    {
        DaoUtil tasmaniaUtil = new DaoUtil();
        tasmaniaUtil.getConnection();
    }
}

I have stored all of the login details within a properties file.

My first question is how would I combine these two classes to incorporate both connections? My second question would be how would do I use the select statement to grab all of the data from SQL Server and then the insert statement to insert into the Oracle Databases?

The tables in SQL Server and Oracle (from SQL Server to Oracle)

1. For MATERIAL_BATCH:

In SQL Server:

MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|EXPIRATION DATE|
MODIFIED_DATETIME 

In SQL Developer:

MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|GOODS_SUPPLIER_NUMBER|
EXPIRATION DATE|INSTIME 

2. For MATERIAL_MASTER:

In SQL Server:

PLANT|MATERIAL_NUMBER|MATERIAL_DESC|MODIFIED_DATETIME 

In SQL Developer:

PLANT|MATERIAL_NUMBER|MATERIAL_DESC|PROFIT_CENTER_NAME|STATUS|INSTIME  

3. For VENDOR:

In SQL Server:

VENDOR_NUMBER|VENDOR_NAME|MODIFIED_DATETIME 

In SQL Developer:

VENDOR_NUMBER|VENDOR_NAME|VENDOR_LOCATION|INSTIME

There are some fields that are not in SQL Server that are in SQL Developer (Oracle). For those I will keep NULL.

7
  • Since when Oracle server is using MSSQL server driver? Commented Nov 16, 2015 at 16:31
  • Data export tool in sql server? Commented Nov 16, 2015 at 16:31
  • @nikpon I am actually using a JDBC connection to connect to Oracle. I just use sql server to view the oracle database. Sorry for the confusion Commented Nov 16, 2015 at 16:43
  • @SeanLange . I was told not to use SSIS. Instead I was told to use sql Server JAR file Commented Nov 16, 2015 at 16:44
  • 1
    I can't wrap my brain around the idea of being forced to use code for a data import process unless this is an ongoing thing. Even so this doesn't seem like anything more complicated than some queries. When you don't include a column in an insert statement the value would become null so just exclude those columns in your insert statement. Commented Nov 16, 2015 at 16:50

2 Answers 2

3

Here's some drafted code on how you might proceed - it will not compile as some methods are missing - but you should be able to fill the blanks from here.

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DBCopy {

    public static void main(String[] args) {

        try {
            //You know how to do this - just rename and copy in...
            Connection sourceCon = getOracleConnection(); 
            Connection targetCon = geSqlServerConnection();

            copyMaterialBatch(sourceCon, targetCon);
            copyMaterialMaster(sourceCon, targetCon);
            copyVendor(sourceCon, targetCon);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    private static void copyMaterialBatch(Connection sourceCon, Connection targetCon) throws SQLException {
        //Try-with-Resource to close all cursors once we're done
        try(//SELECT from source
                PreparedStatement ps = sourceCon.prepareStatement(
                    "SELECT \"MATERIAL NUMBER\", "
                    + "\"BATCH NUMBER\", "
                    + "\"VENDOR BATCH NUMBER\", "
                    + "\"VENDOR NUMBER\", "
                    + "\"EXPIRATION DATE\", "
                    + "\"MODIFIED_DATETIME\" FROM MATERIAL_BATCH");
            //INSERT into target
                PreparedStatement ins = targetCon.prepareStatement(
                        "INSERT INTO MATERIAL_BATCH([MATERIAL NUMBER], "
                    + "[BATCH NUMBER], "
                    + "[VENDOR BATCH NUMBER], "
                    + "[VENDOR NUMBER], "
                    + "[GOODS_SUPPLIER_NUMBER], "
                    + "[EXPIRATION DATE]"
                    + "[INSTIME]) VALUES (?,?,?,?,NULL,?,?)");
            //Perform select / open Cursor
                ResultSet rs = ps.executeQuery()) {
            int batchnr = 0;
            int MAXBATCH = 100;
            while(rs.next()) {
                //Set into INSERT the values we SELECTEd
                ins.setInt(1, rs.getInt("MATERIAL NUMBER")); 
                ins.setInt(2, rs.getInt("BATCH NUMBER")); 
                ins.setInt(3, rs.getInt("VENDOR BATCH NUMBER")); 
                ins.setInt(4, rs.getInt("VENDOR NUMBER"));              
                ins.setTimestamp(5, rs.getTimestamp("EXPIRATION DATE")); 
                ins.setTimestamp(6, rs.getTimestamp("MODIFIED_DATETIME"));
                //Add to Batch (you could executeUpdate here but if you have los of rows...)
                ins.addBatch();
                if(++batchnr % MAXBATCH == 0) {
                    ins.executeBatch();
                }
            }
            //if number of rows was not aligned on MAXBATCH size...
            ins.executeBatch();                     
        }                   
    }
}

Note that Oracle and SQL-Server use different escaping for column names containing blanks. Oracle needs "COLUMN NAME" and SQL-Server wants [COLUMN NAME] instead.

Good Luck.

Edit

Adapted to your real parameter types:

//Set into INSERT the values we SELECTEd
            ins.setString(1, rs.getString("MATERIAL_NUMBER")); 
            ins.setString(2, rs.getString("BATCH_NUMBER")); 
            ins.setString(3, rs.getString("VENDOR_BATCH_NUMBER")); 
            ins.setString(4, rs.getString("VENDOR_NUMBER"));      
            ins.setString(5, rs.getString("GOODS_SUPPLIER_NUMBER"));
            //6th value is always null as specified in INSERT
            ins.setTimestamp(6, rs.getTimestamp("MODIFIED_DATETIME"));
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you. I am looking into this now.
Thanks for your help Jan. I am only having one issue now. I am getting this error: An error occurred while converting the nvarchar value to JDBC data type INTEGER. I believe the sql server variables are listed as nvarchar where as the oracle database is listed as varchar. I am trying to figure out how to convert this cleanly. Any ideas?
So now I am getting this error: The column name GOODS_SUPPLIER_NUMBER is not valid. So this is one of the columns that will be listed as null as this column does not exist in the source connection. Below is the code of where it is picking up Goods Supplier Number. I know I am extremely close. I have listed the piece of the code above. Any ideas on this one? Thanks Sonny
-1

So now I am getting this error: The column name GOODS_SUPPLIER_NUMBER is not valid. So this is one of the columns that will be listed as null as this column does not exist in the source connection. Below is the code of where it is picking up Goods Supplier Number. I know I am extremely close. Any ideas on this one? Thanks Sonny

  private static void copyMaterialBatch(Connection sourceCon, Connection targetCon) throws SQLException {
        //Try-with-Resource to close all cursors once we're done
        try(//SELECT from source
                PreparedStatement ps = sourceCon.prepareStatement(
                    "SELECT [MATERIAL_NUMBER], "
                    + " [BATCH_NUMBER], "
                    + " [VENDOR_BATCH_NUMBER], "
                    + " [VENDOR_NUMBER], "
                    + " [EXPIRATION_DATE], "
                    + " [MODIFIED_DATETIME]  FROM dbo.MATERIAL_BATCH_VIEW");
            //INSERT into target
                PreparedStatement ins = targetCon.prepareStatement(
                        "INSERT INTO MATERIAL_BATCH(MATERIAL_NUMBER, "
                    + "BATCH_NUMBER, "
                    + "VENDOR_BATCH_NUMBER, "
                    + "VENDOR_NUMBER, "
                    **+ "GOODS_SUPPLIER_NUMBER, "**
                    + "EXPIRATION_DATE"
                    + "INSTIME) VALUES (?,?,?,?,NULL,?,?)");
            //Perform select / open Cursor
                ResultSet rs = ps.executeQuery()) {
            int batchnr = 0;
            int MAXBATCH = 1000;
            while(rs.next()) {
                //Set into INSERT the values we SELECTEd
                ins.setString(1, rs.getString("MATERIAL_NUMBER")); 
                ins.setString(2, rs.getString("BATCH_NUMBER")); 
                ins.setString(3, rs.getString("VENDOR_BATCH_NUMBER")); 
                ins.setString(4, rs.getString("VENDOR_NUMBER"));      
                ins.setString(5, rs.getString("GOODS_SUPPLIER_NUMBER"));
                ins.setString(6, rs.getString("EXPIRATION_DATE")); 
                ins.setTimestamp(7, rs.getTimestamp("MODIFIED_DATETIME"));
                //Add to Batch (you could executeUpdate here but if you have los of rows...)
                ins.addBatch();
                if(++batchnr % MAXBATCH == 0) {
                    ins.executeBatch();
                }
            }

So my insert statement now looks like this full when I have removed GOODS_SUPPLIER_NUMBER:

try(//SELECT from source
                    PreparedStatement ps = sourceCon.prepareStatement(
                        "SELECT [PLANT], "
                        + "[MATERIAL_NUMBER], "
                        + "[MATERIAL_DESC], "
                        + "[MODIFIED_DATETIME] FROM dbo.MATERIAL_MASTER_VIEW");
                //INSERT into target
                    PreparedStatement ins = targetCon.prepareStatement(
"INSERT INTO MATERIAL_BATCH(MATERIAL_NUMBER, "
                + "BATCH_NUMBER, "
                + "VENDOR_BATCH_NUMBER, "
                + "VENDOR_NUMBER, "
                + "EXPIRATION_DATE"
                    + "INSTIME) VALUES (?,?,?,?,?,?)");
            //Perform select / open Cursor
                ResultSet rs = ps.executeQuery()) {
            int batchnr = 0;
            int MAXBATCH = 1000;
            while(rs.next()) {
                //Set into INSERT the values we SELECTEd
                ins.setString(1, rs.getString("MATERIAL_NUMBER")); 
                ins.setString(2, rs.getString("BATCH_NUMBER")); 
                ins.setString(3, rs.getString("VENDOR_BATCH_NUMBER")); 
                ins.setString(4, rs.getString("VENDOR_NUMBER"));      
                ins.setString(5, rs.getString("EXPIRATION_DATE")); 
                ins.setTimestamp(6, rs.getTimestamp("MODIFIED_DATETIME"));

So now there are 6 values in the insert statement that match with the 6 values in the ins.setString section.

The error I get is : java.sql.BatchUpdateException: ORA-00913: too many values

I am thinking there is a mismatch in the last column, INSTIME vs MODIFIED_DATETIME.

Again I will make sure to give you the credit on this answer. I just did not want to go back and forth with the code so I kept it where I answered my own question. Thanks again.

Thank you so much. That worked. There is one more thing. So I have Material Batch, Material Master and Vendor. For some reason I am getting an error with Vendor. The error is: Invalid column name 'VENDOR_NAME' Here is the code for Vendor:

      private static void copyVendor(Connection sourceCon, Connection targetCon) throws SQLException {
            //Try-with-Resource to close all cursors once we're done
            try(//SELECT from source
                    PreparedStatement ps = sourceCon.prepareStatement(
                        "SELECT [VENDOR_NUMBER], "
                        + "[VENDOR_NAME], "
                        + "[MODIFIED_DATETIME] FROM dbo.VENDOR_VIEW");
                //INSERT into target
                    PreparedStatement ins = targetCon.prepareStatement(
                            "INSERT INTO VENDOR(VENDOR_NUMBER, "
                        + "VENDOR_NAME, "
                        + "INSTIME) VALUES (?,?,?)");
                //Perform select / open Cursor
                    ResultSet rs = ps.executeQuery()) {
                int vendornr = 0;
                int MAXVENDOR = 1000;
                while(rs.next()) {
                    //Set into INSERT the values we SELECTEd
                    ins.setString(1, rs.getString("VENDOR_NUMBER")); 
                    ins.setString(2, rs.getString("VENDOR_NAME")); 
                    ins.setTimestamp(3, rs.getTimestamp("MODIFIED_DATETIME"));
                    //Add to Batch (you could executeUpdate here but if you have los of rows...)
                    ins.addBatch();
                    if(++vendornr % MAXVENDOR == 0) {
                        ins.executeBatch();
                    }
                }
                //if number of rows was not aligned on MAXBATCH size...
                ins.executeBatch();                     
            }                   


    }

Can't see exactly see what I am missing here. I Have three columns, VENDOR_NUMBER, VENDOR_NAME, and MODIFIED_DATETIME. I know the spelling is correct. This is more of a 'second set of eyes' situation. lol. Thanks again

6 Comments

You should update your question, if you do not intend to answer the question yourself ...at which point I'd be a little annoyed for having spent my time ;-) See edit in my answer for changes suggested.
@Jan I will make sure I will give you the thumbs up on your comment. Sorry about that. so right now I am getting the too many values error. I believe it has something to do with the timestamp. Here is how I modified the code as per you: while(rs.next()) { ins.setString(1, rs.getString("MATERIAL_NUMBER")); ins.setString(2, rs.getString("BATCH_NUMBER")); ins.setString(3, rs.getString("VENDOR_BATCH_NUMBER")); ins.setString(4, rs.getString("VENDOR_NUMBER")); ins.setString(5, rs.getString("EXPIRATION_DATE")); ins.setTimestamp(6, rs.getTimestamp("MODIFIED_DATETIME"));
Please edit your post - and include the insert statement. If number of ? in your statement does not match number of parameters you set (6 in this case) you'd get this error. Or if in INSERT INTO (a, b, c) values( a1,b1,c1,d2) you'd have more values than columns for insert
+ "EXPIRATION_DATE" + "INSTIME would result in EXPIRATION_DATEINSTIME - which would be interpreted as ONE column. "EXPIRATION_DATE, " + "INSTIME" should fix this
@Jan. Thank you so much. That was a stupid mistake on my part. So one more thing. I have added one more addition of an error to the answer I layed out above.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.