4

私は以下を実行したい:

(PROCESSING DBの取り出した行からPRESENTATION DBへの行の転送)

    PreparedStatement stmt;
    Statement st;
    Connection conn = ConnectionManager.getInstance().getConnection(ConnectionManager.PRESENTATION_DB);
    try {
        conn.setAutoCommit(false);
        stmt = conn.prepareStatement(
               "insert into customer (name,category,age) values (?,?,?)");  
                    stmt.clearParameters();
                    stmt.setString(1,"name2");
                    stmt.setString(2,"cat2");
                    stmt.setInt(3,25);
                    stmt.addBatch();
                    stmt.clearParameters();
                    stmt.setString(1,"name3");
                    stmt.setString(2,"cat3");
                    stmt.setInt(3,25);
                    stmt.addBatch();
                    stmt.clearParameters();
                    stmt.setString(1,"name4");
                    stmt.setString(2,"cat2");
                    stmt.setInt(3,25);
                    stmt.addBatch();
                    stmt.clearParameters();
                    stmt.setString(1,"name4");
                    stmt.setString(2,"cat2");
                    //stmt.setInt(3,25);

                    //this is parameter with false input
                    stmt.setString(3,"null"); 

                    stmt.addBatch();
                    stmt.clearParameters();
                    stmt.setString(1,"name5");
                    stmt.setString(2,"cat5");
                    stmt.setInt(3,25);
                    stmt.addBatch();
                    stmt.clearParameters();

        int [] updateCounts = stmt.executeBatch();
        conn.commit();
        conn.setAutoCommit(true);

                    stmt.close();
        conn.close();
    } 
    catch(BatchUpdateException b) {
                    System.err.println("-----BatchUpdateException-----");
                    System.err.println("SQLState:  " + b.getSQLState());
                    System.err.println("Message:  " + b.getMessage());
                    System.err.println("Vendor:  " + b.getErrorCode());
                    System.err.print("Update counts:  ");
                    int [] updateCounts = b.getUpdateCounts();
                    for (int i = 0; i < updateCounts.length; i++) {
                            System.err.print(updateCounts[i] + "   ");
                    }
                    System.err.println("");
            }
    catch (Exception e) {
        e.printStackTrace();
    }

この特定の行なしでバッチ処理を再実行できる例外の原因となった行を特定するにはどうすればよいですか? (行のフィールド hasError を更新することにより)。

現在、オブジェクトをバッチで保存していないので、エラーが発生した場合は行をマークし、その行をスキップして別の行の処理 (つまり、保存/転送および削除) に進むことができます。

ありがとう!

アップデート:

OK、次のコードを使用して行を追跡しました (いずれかの行でエラーが発生した場合)。

        public static void processUpdateCounts(int[] updateCounts) {
            for (int i=0; i<updateCounts.length; i++) {
                if (updateCounts[i] >= 0) {
                    // Successfully executed; the number represents number of affected rows
                    logger.info("Successfully executed: number of affected rows: "+updateCounts[i]);
                } else if (updateCounts[i] == Statement.SUCCESS_NO_INFO) {
                    // Successfully executed; number of affected rows not available
                    logger.info("Successfully executed: number of affected rows not available: "+updateCounts[i]);
                } else if (updateCounts[i] == Statement.EXECUTE_FAILED) {
                    logger.info("Failed to execute: "+updateCounts[i]);
                    // Failed to execute
                }
            }
        }

そして、次の行を追加しました:

        processUpdateCounts(updateCounts);

エラーの有無にかかわらず変更を確認できますが、BatchUpdateException が機能していないようです。

4

4 に答える 4

0

MySQL で mysql-connector-java-3.1.14 を使用しています。このトピックの上部にある更新 (BatchUpdateException と getUpdateCounts を使用) は正しく機能しています。これで、バッチ挿入/更新で問題のある行を見つけることができます。

于 2013-05-13T12:56:22.007 に答える
0

コマンドの実行に役立つ DB レイヤーを作成します。SQL コマンドが失敗した場合は、while ループなどを使用して数回再試行し、数回失敗してもログに記録します。

于 2011-05-08T09:24:22.760 に答える
0

既に指摘したように、バッチ中に失敗した SQL ステートメントのインデックスにのみアクセスできます。つまり、実行に失敗した同じステートメントを再作成するには、次のようにパラメーターをインデックス可能な方法で保存する必要があります。

List<...>paramList = new ArrayList<...>();
for (... params in paramList) {
    stmt.clearParameters();
    stmt.setString(...something involving params...);
    // etc.
}

このようにして、getUpdateCountswithEXECUTE_FAILED配列のインデックスを使用して、失敗の原因となったパラメーターを特定できます。

于 2011-03-07T15:29:41.907 に答える