我有主表AAAA和表BBBB,其中有FK到表AAAA。FK约束为ON删除set null。在表BBBB上也有一个ON DELETE触发器。在这个触发器中,从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删除!
为什么要执行trigger呢?
在我的测试中,当删除父表时,AFTER DELETE 和 AFTER UPDATE都会触发子表上的fire,这是反直觉的。我不确定这是否是预期的行为-可能是一个bug,但我不确定。
然而,子表上的行级触发器只在预期的情况下触发——即,不会触发的AFTER DELETE触发器,但是触发的AFTER UPDATE触发器。
无论如何,解决这个问题的方法是使用AFTER DELETE FOR EACH ROW触发器而不是语句级触发器。如果需要,在after语句触发器中记录要处理的包中的行id。