删除触发器后有什么问题?
What's wrong with that AFTER DELETE TRIGGER?
我正在尝试使用触发器在删除另一个(通过 SQL)时清除一些 @OneToOne
相关实体。假设我有一个 Person
和一个 OrgUnit
都引用了一些 Address
。 Address
映射到 ADDRESS_ID
和相关的外键约束。
以下触发器编译正常:
CREATE OR REPLACE TRIGGER ON_DELETE_PERSON
AFTER DELETE ON PERSON
FOR EACH ROW
BEGIN
DELETE FROM ADDRESS WHERE ID = :OLD.ADDRESS_ID;
END;
/
但是每当我尝试删除 Person
时,都会抛出以下错误:
DELETE FROM PERSON WHERE ID = 21179
ORA-04091: table MY_SCHEMA.PERSON is mutating, trigger/function may not see it
ORA-06512: in "MY_SCHEMA.ON_DELETE_PERSON", row 2
ORA-04088: error during execution of trigger 'MY_SCHEMA.ON_DELETE_PERSON'
必须更改什么才能使此触发器起作用?
在 Java 代码中,我可以简单地用 CascadeStyle.DELETE
来处理这个问题......但我想将该责任转移到数据库以允许所有数据的正确 ON DELETE CASCADE
行为.
-- CASCADE DELETE on ORGUNIT deletion...
ALTER TABLE PERSON ADD CONSTRAINT PERSON_F01
FOREIGN KEY (ORGUNIT_ID) REFERENCES ORGUNIT (ID)
ON DELETE CASCADE ENABLE VALIDATE;
-- SET NULL on ADDRESS deletion...
ALTER TABLE PERSON ADD CONSTRAINT PERSON_F02
FOREIGN KEY (ADDRESS_ID) REFERENCES ADDRESS (ID)
ON DELETE SET NULL ENABLE VALIDATE;
因此,删除 ORGUNIT
也会自动删除所有相关的 PERSON
...但是 ADDRESS
会保留在数据库中。上面的 TRIGGER 就是为了处理这种情况。
所以在一些评论之后弹出答案:
ON DELETE SET NULL
的 FK 约束会返回到 table 并导致该异常。看来我不能两者兼得...
我将摆脱 ON DELETE
定义,并在这种情况下冒 FK 约束错误的风险。通过触发器的级联删除对我来说具有更高的价值。
我正在尝试使用触发器在删除另一个(通过 SQL)时清除一些 @OneToOne
相关实体。假设我有一个 Person
和一个 OrgUnit
都引用了一些 Address
。 Address
映射到 ADDRESS_ID
和相关的外键约束。
以下触发器编译正常:
CREATE OR REPLACE TRIGGER ON_DELETE_PERSON
AFTER DELETE ON PERSON
FOR EACH ROW
BEGIN
DELETE FROM ADDRESS WHERE ID = :OLD.ADDRESS_ID;
END;
/
但是每当我尝试删除 Person
时,都会抛出以下错误:
DELETE FROM PERSON WHERE ID = 21179
ORA-04091: table MY_SCHEMA.PERSON is mutating, trigger/function may not see it
ORA-06512: in "MY_SCHEMA.ON_DELETE_PERSON", row 2
ORA-04088: error during execution of trigger 'MY_SCHEMA.ON_DELETE_PERSON'
必须更改什么才能使此触发器起作用?
在 Java 代码中,我可以简单地用 CascadeStyle.DELETE
来处理这个问题......但我想将该责任转移到数据库以允许所有数据的正确 ON DELETE CASCADE
行为.
-- CASCADE DELETE on ORGUNIT deletion...
ALTER TABLE PERSON ADD CONSTRAINT PERSON_F01
FOREIGN KEY (ORGUNIT_ID) REFERENCES ORGUNIT (ID)
ON DELETE CASCADE ENABLE VALIDATE;
-- SET NULL on ADDRESS deletion...
ALTER TABLE PERSON ADD CONSTRAINT PERSON_F02
FOREIGN KEY (ADDRESS_ID) REFERENCES ADDRESS (ID)
ON DELETE SET NULL ENABLE VALIDATE;
因此,删除 ORGUNIT
也会自动删除所有相关的 PERSON
...但是 ADDRESS
会保留在数据库中。上面的 TRIGGER 就是为了处理这种情况。
所以在一些评论之后弹出答案:
ON DELETE SET NULL
的 FK 约束会返回到 table 并导致该异常。看来我不能两者兼得...
我将摆脱 ON DELETE
定义,并在这种情况下冒 FK 约束错误的风险。通过触发器的级联删除对我来说具有更高的价值。