ORA-04082:表级触发器中不允许使用新引用或旧引用

Mar*_*ina 23 oracle triggers

我有一个名为per的表.在每个表中,我有一个名为"fl1"的字段和另一个名为"fl2"的字段.更新记录时,我想检查"fl1"的值是否已更改".如果值已更改,请使用"fl1"中的新值更新"fl2"列.

我想出了这个触发器

CREATE OR REPLACE TRIGGER Flag
AFTER INSERT OR UPDATE on per
REFERENCING NEW AS NEW OLD AS OLD
BEGIN
  If :New.fl1 != :Old.fl1 Then
        :New.fl2:= :new.fl1;
  End If;
END;
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我得到"ORA-04082:表级触发器中不允许新的或旧的引用"

我正在考虑的另一个选项(不确定它是否有效),只是用"fl1"的值更新"fl2"的值,无论"fl1"的值是否已经改变.

UPDATE

添加了"For Each Row"并更改了"在INSERT或UPDATE之后更新"为"BEFORE INSERT OR UPDATE".它正在发挥作用.

CREATE OR REPLACE TRIGGER Flag
BEFORE INSERT OR UPDATE on per
REFERENCING NEW AS NEW OLD AS OLD

FOR EACH ROW
BEGIN
If :New.fl1 != :Old.fl1 Then
   :New.fl2:= :new.fl1;
End If;
END;
Run Code Online (Sandbox Code Playgroud)

Dav*_*dge 23

DML触发器可以定义为表级别或行级别.

对于表上的每个操作,表级触发器触发一次,因此如果更新30行,那么就表触发而言,这是一个操作.表触发器无法深入了解哪些行被修改,但可用于记录执行操作的事实.

在这种情况下,您需要一个行级触发器,它要求"FOR EACH ROW"包含在触发器定义中.如果您不想更改引用新旧行的方式,则"REFERENCING"子句是可选的.

http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/triggers.htm#BABCIBBJ

但不确定这里的练习是什么意思.您是否考虑过引用fl1而不是fl2?


Mar*_*ina 7

最终工作代码:

CREATE OR REPLACE TRIGGER Flag
BEFORE INSERT OR UPDATE on per
REFERENCING NEW AS NEW OLD AS OLD

FOR EACH ROW
BEGIN
If :New.fl1 != :Old.fl1 Then
   :New.fl2:= :new.fl1;
End If;
END;
Run Code Online (Sandbox Code Playgroud)