1. ホーム
  2. oracle

[解決済み] ORA-04082: テーブルレベルのトリガーで NEW または OLD 参照は許可されません。

2022-02-07 14:07:57

質問

という名前のテーブルがあります。 について . その中で につき テーブルには、"fl1" というフィールドと "fl2" という別のフィールドがあります。 レコードを更新するときに、"fl1"の値が変更されたかどうかをチェックしたいのです"。値が変更された場合、"fl2"列を"fl1"から新しい値で更新します。

こんなトリガーを思いつきました。

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;

ORA-04082 が表示されます。を実行すると、「NEW または OLD 参照はテーブル レベル トリガで許可されていません。

私が考えていた他のオプションは(効率的かどうかはわかりませんが)、"fl1" の値が変更されたかどうかに関係なく、単純に "fl2" の値を "fl1" の値で更新することでした。

アップデイト

For Each Row" を追加し、 "AFTER INSERT OR 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;

解決方法は?

DMLトリガーは、テーブルレベルまたは行レベルで定義されます。

テーブルレベル トリガは、テーブル上の各操作に対して一度だけ起動します。従って、30行を更新すると、テーブルトリガに関する限り、それは1つの操作です。テーブルトリガは、どの行が変更されたかを知ることはできませんが、操作が実行されたことを記録するために使用することができます。

この場合、行レベル トリガが必要で、トリガ定義に "FOR EACH ROW" が含まれることが必要です。新旧の行を参照する方法を変更したくない場合、"REFERENCING"節はオプションです。

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

ここでの演習の意味がよくわからないけど。fl2の代わりにfl1を参照することは考えなかったのでしょうか?