【问题标题】:Why oracle trigger on delete is executed when foreign key is set to null为什么当外键设置为空时执行删除时的oracle触发器
【发布时间】:2013-03-06 15:00:42
【问题描述】:

我有主表 AAAA 和表 BBBB,它们有 FK 到表 AAAA。 FK 约束为 ON 删除设置为空。 还有触发器 ON DELETE ON table 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 中删除!

那么为什么要执行触发器呢?

【问题讨论】:

  • 触发器中的delete from aaa... 是什么?如果它在你的真实触发器中是“活跃的”,它导致递归。
  • 当然,我理解递归,但如果我留在触发器中,只需打印一些行,它就会被调用并工作。问题是为什么在表 bbbb 上没有删除时执行(调用)该触发器(并且此操作应该导致触发器执行)。
  • 在 Oracle 11.1.0.7.0 上复制

标签: oracle triggers foreign-keys constraints


【解决方案1】:

在我的测试中,删除父表时,AFTER DELETE AFTER UPDATE 触发器都会在子表上触发,这是违反直觉的。我不确定这是否是预期的行为 - 可能是一个错误,但我不确定。

但是,子表上的行级触发器只会按预期触发 - 即触发 AFTER DELETE FOR EACH ROW 触发器,但触发了 AFTER UPDATE FOR EACH ROW 触发器 /em> 被解雇了。

无论如何,解决这个问题的方法是使用 AFTER DELETE FOR EACH ROW 触发器而不是语句级触发器。如果需要,在 after 语句触发器中记录要处理的包中的行 ID。

【讨论】:

  • 谢谢,记住更改的行的解决方法很好,但由于我们使用更多的数据库,我们决定在应用程序后端使用解决方案。无论如何,如果有人知道它为什么会这样,请告诉我们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多