2

jdbcを使用して実行しようとしているOracleクエリがあります。以下はクエリです。

insert into bd_vehicles_temp select * from bd_vehicles_temp_1

テーブル bd_vehicles_temp_1 には、約 7000 ~ 10000 行が含まれています。bd_vehicles_temp_1 の主キーが bd_vehicles_temp に既に存在する場合、SQLException : Unique key constraint が発生します。

pstmt.executeUpdate()私のコードでは例外行はオフコースです。例外を引き起こす bd_vehicles_temp_1 の行を特定する方法はありますか。

または、bd_vehicles_temp_1 の行をループして、各行を 1 つずつ挿入する必要がありますか?

前もって感謝します !

4

3 に答える 3

7

問題の原因となっている行を特定する唯一の方法 (私が知っている) は、Oracle の「エラーをログに記録する」機能を使用することです。そうinsertすれば、例外はスローされず、制約に違反する行は指定されたエラー テーブルに書き込まれます。

そのためには、まず、拒否された行を保持するログ テーブルを作成する必要があります。

EXECUTE DBMS_ERRLOG.CREATE_ERROR_LOG('BD_VEHICLES_TEMP');

という名前のテーブルが作成されますERR$_BD_VEHICLES_TEMP

次に、ステートメントを次のように変更します。

insert into bd_vehicles_temp 
select * 
from bd_vehicles_temp_1
LOG ERRORS REJECT LIMIT UNLIMITED;

行が制約の検証に失敗した場合でも、ステートメントは続行されます。ERR$_BD_VEHICLES_TEMPステートメントが終了したら、エラー メッセージと値を含む、制約に違反した行のテーブルの内容を確認できます。

(編集):最初のエラーで停止したい(そしてログテーブルでそれを確認したい)場合は、REJECT LIMIT UNLIMITED句を省略してください。

詳細はマニュアルに記載されています:

于 2013-08-27T06:23:39.883 に答える
2

テーブルに挿入しようとしていますよね?pstmt.executeUpdate()の代わりに使用する必要がありpstmt.execute()ます。テーブルに既存のレコードがある場合、このステートメントが複数回実行される場合は、すべての行を削除して再度追加することをお勧めします。

于 2013-08-27T06:07:59.307 に答える
2

使用できる例外の原因となる列がわかっている場合 (Oracle 固有)

SELECT col FROM bd_vehicles_temp
INTERSECT
SELECT col FROM bd_vehicles_temp_1;

両方のテーブルにあるすべての行を識別します。

于 2013-08-27T06:06:43.643 に答える