0

Oracle データベースでトリガーを作成しようとしていますが、when 条件に問題があります。使用しようとすると、「無効な関係演算子」が表示されます

   create or replace TRIGGER SQLTEST.TRIGGER_TESTE
AFTER INSERT OR UPDATE ON SQLDBA.VT_TABLE
FOR EACH ROW
WHEN (INSERTING OR NEW.FIELD_1 is null and OLD.FIELD_1 is not null or NEW.FIELD_1 <> OLD.FIELD_1) 

DECLARE
VAR_FIELD_1 VT_LOG_TABLE.FIELD_1%TYPE;

BEGIN

SELECT SQLDBA.SEQ_LOG_TABLE.NEXtval into VAR_FIELD_1
FROM dual;


INSERT INTO VT_LOG_TABLE
(FIELD_0,VAR_FIELD_1,FIELD_2,FIELD_3,FIELD_1, FIELD_4 )
VALUES( :NEW.FIELD_0,VAR_FIELD_1, :NEW.FIELD_2, :NEW.FIELD_3, :NEW.FIELD_1,SYSDATE);

END TRIGGER_TESTE;

その条件を作る正しい方法は何ですか?

4

2 に答える 2

3

グレースミールの言うとおり、WHEN節がわかりませんINSERTINGold.field_1 is nullnull 許容フィールドのように見えるため、挿入を示すために信頼できるかどうかはわかりません(new.field_1明らかに null になる可能性があるため)。できない場合は、ロジックをブロックに移動できます。

create or replace trigger vt_trigger
after insert or update on vt_table
for each row
declare
    do_logging boolean := false;
begin
    if inserting then
        do_logging := true;
    elsif (:new.field_1 is null and :old.field_1 is not null)
        or (:new.field_1 is not null and :old.field_1 is null)
        or (:new.field_1 <> :old.field_1)
    then
        do_logging := true;
    end if;

    if do_logging then
        insert into vt_log_table (field_0, var_field_1, field_2, field_3,
            field_1, field_4)
        values (:new.field_0, seq_log_table.nextval, :new.field_2, :new.field_3,
            :new.field_1, sysdate);
    end if;
end vt_trigger;
/

チェックを次のように少し変更しました。

    elsif (:new.field_1 is null and :old.field_1 is not null)
        or (:new.field_1 is not null and :old.field_1 is null)
        or (:new.field_1 <> :old.field_1)

... field_1null から null に変更されたか、または null 以外の値から別の値に変更されたかを検出します。多分あなたはそれを望まないでしょう、部分的なチェックは私には少し奇妙に見えました. field_1何らかの方法で変更された場合、またはもちろん新しい行を挿入している場合にのみログに記録する必要があると想定しています。

于 2013-02-27T21:17:40.823 に答える
2

同様のことを試してみましたが、OracleはWHEN条件のINSERTING値が好きではありません。NEWでもOLDでも、入れてもOKのようです。

実験から、これを WHEN 条件に追加すると、トリガーが INSERTS で起動するように見えます。

OR OLD.FIELD_1 IS NULL

だから、次のようなことを試してください:

create or replace TRIGGER SQLTEST.TRIGGER_TESTE
AFTER INSERT OR UPDATE ON SQLDBA.VT_TABLE
FOR EACH ROW
WHEN (NEW.FIELD_1 is null and OLD.FIELD_1 is not null
   or NEW.FIELD_1 <> OLD.FIELD_1
   or OLD.FIELD_1 IS NULL)

DECLARE

... and so on

これが複雑すぎる場合は、2 つのトリガーを作成できます。1 つは WHEN 条件付きの UPDATE 用で、もう 1 つは条件なしの INSERT 用です。

AFTER INSERT OR UPDATE OF Field_1 ON VT_TABLE としてトリガーを定義することもできます。

create or replace trigger vt_trigger
after insert or update of field_1 on vt_table
for each row
begin
    insert into vt_log_table (field_0, var_field_1, field_2, field_3,
        field_1, field_4)
    values (:new.field_0, seq_log_table.nextval, :new.field_2, :new.field_3,
        :new.field_1, sysdate);
end vt_trigger;
/
于 2013-02-27T19:31:13.980 に答える