1

プライマリ テーブル AAAA と、テーブル AAAA への FK を持つテーブル BBBB があります。FK 制約は ON DELETE SET NULL です。トリガー ON DELETE ON テーブル BBBB もあります。このトリガーには、AAAA からの削除があります... AAAA からの削除が実行されると、なぜこのトリガーが実行されるのですか? (まあ、再帰例外があるので実行されません)。

CREATE TABLE AAAA
  (
    "AAAA_PK"    NUMBER NOT NULL ENABLE,
    "AAAA_VALUE" NUMBER,
    CONSTRAINT "AAAA_PK" PRIMARY KEY ("AAAA_PK")
  )

CREATE TABLE "BBBB"
 (
  "BBBB_PK" NUMBER NOT NULL ENABLE,
  "BBBB_FK" NUMBER DEFAULT NULL,
  CONSTRAINT "BBBB_PK" PRIMARY KEY ("BBBB_PK"),
  CONSTRAINT "BBBB_AAAA_FK1" FOREIGN KEY ("BBBB_FK") REFERENCES AAAA ("AAAA_PK") ON
  DELETE    SET NULL ENABLE
)

CREATE OR REPLACE TRIGGER TRIG_ON_AFTER_BBBB_DELETE_ALL AFTER
  DELETE ON bbbb 
 BEGIN 
 -- delete from aaaa where ....
 dbms_output.put_line('TRIGGER EXECUTED');
END;

AAAA(1,1) や BBBB(1,1) などのデータを追加します

AAAA から行を削除すると、BBBB の FK が null に設定されると予想していましたが、失敗します

ORA-00036: maximum number of recursive SQL levels (50) exceeded
ORA-06512: at TRIG_ON_AFTER_BBBB_DELETE_ALL, line 2
ORA-04088: error during execution of trigger TRIG_ON_AFTER_BBBB_DELETE_ALL

出力印刷だけでトリガーがあれば実行されますが、テーブルBBBBから削除していません!

では、なぜトリガーが実行されるのでしょうか。

4

1 に答える 1

0

私のテストでは、親を削除すると、AFTERDELETEAFTERUPDATEの両方が子テーブルで起動しますが、これは直感に反します。これが予期された動作であるかどうかはわかりません。おそらくバグですが、よくわかりません。

ただし、子テーブルの行レベルのトリガーは期待どおりにのみ起動します。つまり、AFTER DELETE FOR EACH ROWトリガーは起動されませんが、AFTER UPDATE FOREACHROWトリガー起動されます。

とにかく、これを回避する方法は、ステートメントレベルのトリガーの代わりにAFTER DELETE FOREACHROWトリガーを使用することです。必要に応じて、afterステートメントトリガーで処理されるパッケージに行IDを記録します。

于 2013-03-19T05:08:22.797 に答える