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

正如 Graceemile 所说,该WHEN子句不理解INSERTING。我不确定您是否可以依靠old.field_1 is null来指示插入,因为它看起来像一个可为空的字段(因为new.field_1显然可以为空)。如果你不能,那么你可以将逻辑移到块中:

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_1已从 null 更改为 null 或从一个非 null 值更改为另一个;也许你不想要那个,部分检查对我来说有点奇怪。我假设您只想记录是否field_1发生了任何变化,或者您当然要插入新行。

于 2013-02-27T21:17:40.823 回答
2

我刚刚尝试了类似的方法,Oracle 不喜欢 WHEN 条件中的 INSERTING 值。使用 NEW 和 OLD 似乎没问题,即使插入也是如此。

从实验来看,如果您将其添加到您的 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

如果这变得太复杂,您可以创建两个触发器:一个用于带有 WHEN 条件的 UPDATE,另一个用于不带条件的 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 回答