0

私は、Oracleデータベースからデータを取得し、Javaプログラミングを使用してMSSQL Server 2008データベースに挿入する機能に取り組んでいます.する)。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

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 に答える
0

を実行する前に、を実行して、挿入するレコードが既に存在するかどうかを確認insert into tblStates...できます。その場合は をスキップし、そうでない場合は を実行します。selectsqlconninsertinsert

ただし、これはあまり効率的ではありません。レコードごとにselect. 10万行のテーブルを想像してください...

パフォーマンスを向上させるために、次のことを行うことができます。を反復処理する前に、すべてのレコードを からにoracle_rsロードします。(コメントによると)主キーがないため、ターゲットデータベースに挿入される1行の値を含むという名前のクラスを定義することをお勧めします。これにより、ターゲット データベースに存在するかどうかをメモリ内でチェックできます。ソース データベースからフェッチしたばかりのレコードがメモリ内コレクションに含まれている場合は、それをターゲット データベースに挿入しないでください。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 に答える