Oracle データベースで大量の (最大 1000000 までの) SQL ステートメントを実行する必要があります。これらのステートメントは、最後に参照整合性のある状態になる必要があり、エラーが発生した場合はすべてのステートメントをロールバックする必要があります。これらのステートメントは参照順ではありません。そのため、外部キー制約が有効になっている場合、ステートメントの 1 つが外部キー違反を引き起こす可能性がありますが、この違反は後で実行されるステートメントで修正されます。
最初に外部キーを無効にして、すべてのステートメントが実行された後に有効にしようとしました。実際に外部キー違反があったときにロールバックできると思っていました。私は間違っていましたが、Oracle のすべての DDL ステートメントはコミットで始まっていることがわかったので、この方法でステートメントをロールバックする方法はありませんでした。外部キーを無効にするスクリプトは次のとおりです。
begin
for i in (select constraint_name, table_name from user_constraints
where constraint_type ='R' and status = 'ENABLED')
LOOP execute immediate 'alter table '||i.table_name||' disable constraint
'||i.constraint_name||'';
end loop;
end;
いくつかの調査の結果、この場合のように自律型トランザクションで DDL ステートメントを実行することが推奨されていることがわかりました。そこで、自律型トランザクションで DDL ステートメントを実行しようとしました。これにより、次のエラーが発生しました。
ORA-00054: リソースがビジーで、NOWAIT を指定して取得しています
これは、メイン トランザクションがまだテーブルに対して DDL ロックを保持しているためだと推測しています。
ここで何か間違ったことをしていますか、またはこのシナリオを機能させる他の方法はありますか?