0

我正在开发一个功能,我应该从 oracle 数据库中获取数据并将其插入到使用 Java 编程的 MSSQL Server 2008 数据库中。(我知道还有其他选择,如 oracle 金门,链接服务器。但这就是我被问到的去做)。我能够从 oracle 服务器获取数据并将其插入 sql 服务器。但问题在于冗余。即,每当我触发或运行程序时,就会插入重复的记录,因为我应该每 6、12、24 小时执行一次。我不希望它发生。那么我该如何避免它,因为源数据库具有不同的连接而目标数据库是不同的连接。

以下是代码。我希望您能帮我解决避免插入重复数据的问题。

/*TO Retrieve data from oracle database and insert it into sql server*/

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;


public class states {

    public static void main(String[] args) {
        String statecode, statename;
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver")
                    .newInstance();

            // Connecting to Oracle
            Connection oracleconn = DriverManager.getConnection(
                    "jdbc:oracle:thin:@ipaddress:1521:orcl",
                    "uname", "pwd");
            // Connecting to SQL SERVER
            Connection sqlconn = DriverManager
                    .getConnection("jdbc:sqlserver://localhost:1433;databaseName=dbname;user=sa;password=pwd;");
            System.out.println("connected");



            // create Statement for sql and oracle

            /*
             * A Statement is an interface that represents a SQL statement. You
             * execute Statement objects, and they generate ResultSet objects,
             * which is a table of data representing a database result set. You
             * need a Connection object to create a Statement object.
             */
            Statement oraclestatement = oracleconn.createStatement();

            Statement sqlstatement = sqlconn.createStatement();

            /*
             * The ResultSet interface provides methods for retrieving and
             * manipulating the results of executed queries, and ResultSet
             * objects can have different functionality and characteristics.
             */
            ResultSet oracle_rs = oraclestatement
                    .executeQuery("select substr(TRIIDTX,1,2),TRINAMETX from  T_TRISTATE  WHERE TRIIDTX IS NOT NULL AND TRINAMETX IS NOT NULL AND TRINAMETX  not LIKE '%''%' ESCAPE '/'");
            System.out.println("TRICODETX   TRINAMETX \n");

            // String dummytable="tbldummystate";

            while (oracle_rs.next()) {

                System.out.println("     " + oracle_rs.getString(1) + "      "
                        + oracle_rs.getString(2) + "   ");

                // converting the string value into integer value

                statecode = oracle_rs.getString(1);
                statename = oracle_rs.getString(2);

                sqlstatement
                        .executeUpdate("insert into tblStates(StateCode,StateName) values('"
                                + statecode + "','" + statename + "')");

                // sqlstatement.execute ();


            }// end of while loop

        } catch (Exception e) {
            e.printStackTrace();
        }

    }// end of
}
4

2 回答 2

0

在执行之前,insert into tblStates...您可以在select上执行sqlconn并检查您要插入的记录是否已经存在。如果是,请跳过insert,否则,执行insert

但是,这不是很有效,对于每条记录,您将执行一个select. 想象一个有 100k 行的表......

为了提高性能,您可以执行以下操作。在迭代 之前,将所有记录oracle_rs加载到. 由于没有主键(根据您的评论),我建议您在其中定义一个名为的类,其中包含要插入目标数据库的一行的值。这使您可以对目标数据库中的存在进行内存检查。如果您的内存中集合包含您刚刚从源数据库中获取的记录,请不要将其插入目标数据库。tblStatesListList<Foo>Foo

在伪代码中,它大致如下所示:

String selectAllQuery = "select StateCode, StateName from tblStates";
Statement selectAllstatement = sqlconn.createStatement();
ResultSet selectAllResultset = selectAllstatement.executeQuery(selectAllQuery);

List<Foo> cache = new ArrayList<Foo>();
while (selectAllResultset.next()) {
    cache.add(new Foo(selectAllResultset.getString("StateCode"),
                      selectAllResultset.getString("StateName")));
}

while (oracle_rs.next()) {
    statecode = oracle_rs.getString(1);
    statename = oracle_rs.getString(2);

    if (!cache.contains(new Foo(statecode,
                                statename))) {
        sqlstatement.executeUpdate("insert into tblStates"
            + "(StateCode,StateName) values('"
            + statecode + "','" + statename + "')");
    }
}

像这样的Foo课程:

public class Foo {
    private String stateName;
    private String stateCode;
    // Insert constructor with two arguments
    // Insert equals() implementation based on the two instance variables
}
于 2013-07-22T09:16:03.513 回答
0

也许使用MERGE会做到这一点?

就像是:

.executeUpdate("
MERGE INTO tblStates AS Target
USING (VALUES ('"+ statecode + "','" + statename + "'))
       AS Source (StateCode, StateName)
ON Target.StateCode = Source.StateCode
WHEN NOT MATCHED BY TARGET THEN
    INSERT (StateCode, StateName) VALUES ('"+ statecode + "','" + statename + "');
)";

编辑:如果要更新目标表中已存在的 StateCode 的 StateName,如果它在源表中发生更改,则可以在WHEN NOT MATCHED子句之前的语句中添加以下内容:

WHEN MATCHED THEN UPDATE SET StateName = ('" + statename + "')"

于 2013-07-22T09:32:40.357 回答