为什么当外键设置为null时执行oracle delete触发器?



我有主表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。

最新更新