次の列を持つ CUSTOMERS という名前のテーブルがあります。
CUSTOMER_ID (NUMBER)、DAY(DATE)、REGISTERED_TO(NUMBER)
テーブルにはさらに列がありますが、上記の列のみが主キーとして一緒に定義されているため、私の質問には関係ありません
このアプリケーションでは、このテーブルに大量の挿入を行うため、MERGEを使用せずに次のステートメントを使用します。
INSERT INTO CUSTOMERS (CUSTOMER_ID , DAY, REGISTERED_TO)
SELECT ?, ?, ?
FROM DUAL WHERE NOT EXISTS
(SELECT NULL
FROM CUSTOMERS
WHERE CUSTOMER_ID = ?
AND DAY = ?
AND REGISTERED_TO = ?
)";
バッチ機能を利用したPreparedStatement
オブジェクトを使用して、お客様ごとのお申し込みの流れで集めた大量のレコードを挿入します。
問題は、時々次のエラーが発生することです:
ORA-00001: 一意の制約 (CUSTOMERS_PK) に違反しています
奇妙なことは、バッチ挿入を使用せず、各レコードを 1 つずつ (単純に実行して) 挿入すると、エラーが発生しないことです。pstmt.execute()
挿入ステートメントに何か問題がありますか?jdbc ドライバー ? バッチ メカニズムを正しく使用していませんか?
これが私の挿入ループの半疑似コードです:
pstmt = conn.prepareStatement(statement);
pstmt.setQueryTimeout(90);
for each customer :
- pstmt.setObject(1, customer id);
- pstmt.setObject(2, current day);
- pstmt.setObject(3, registered to);
- pstmt.addBatch();
end for
pstmt.executeBatch();
これはすべて try/catch/finally ブロックで囲まれており、このプロセスの最後にステートメントと接続が確実に閉じられます。