すべての外部キーに適切な制約があると仮定すると、DB のどこにも参照されていない行を削除する単純な SQL ステートメントはありますか?
delete from the_table
子レコードを持つ行をスキップするだけの簡単なものですか?
テーブルを手動でループしたり、のようなものを追加したりしないようにしていwhere the_SK not in (a,b,c,d)
ます。
すべての外部キーに適切な制約があると仮定すると、DB のどこにも参照されていない行を削除する単純な SQL ステートメントはありますか?
delete from the_table
子レコードを持つ行をスキップするだけの簡単なものですか?
テーブルを手動でループしたり、のようなものを追加したりしないようにしていwhere the_SK not in (a,b,c,d)
ます。
DELETE
エラーロギングを含む10gの拡張ステートメントを使用できる場合があります。
最初DBMS_ERRLOG
にログテーブルを作成するために使用します(これは、いくつかの追加のプレフィックス列を含む元のテーブルの単なるコピーですORA_ERR_MESG$, ..., ORA_ERR_TAG$
:)
execute dbms_errlog.create_error_log('parent', 'parent_errlog');
これで、deleteステートメントのLOG ERRORS句を使用して、既存の整合性制約を持つすべての行をキャプチャできます。
delete from parent
log errors into parent_errlog ('holding-breath')
reject limit unlimited;
この場合、「holding-breath」コメントがORA_ERR_TAG$
列に表示されます。
ここで完全なドキュメントを読むことができます。
親テーブルが巨大で、数行の漂遊行のみを削除しようとしている場合parent_errlog
は、基本的にテーブルの複製であるparent
テーブルになります。これがうまくいかない場合は、長い道のりでそれを行う必要があります。
これを行う 1 つの方法は、次のように記述することです。
eForeign_key_violation EXCEPTION;
PRAGMA EXCEPTION_INIT(eForeign_key_violation, -2292);
FOR aRow IN (SELECT primary_key_field FROM A_TABLE) LOOP
BEGIN
DELETE FROM A_TABLE A
WHERE A.PRIMARY_KEY_FIELD = aRow.PRIMARY_KEY_FIELD;
EXCEPTION
WHEN eForeign_key_violation THEN
NULL; -- ignore the error
END;
END LOOP;
子行が存在する場合、DELETE は失敗し、行は削除されず、次のキーに進むことができます。
テーブルが大きい場合、これにはかなりの時間がかかる場合があることに注意してください。