当前一个值为null时,触发器不会触发

时间:2015-01-29 04:45:20

标签: sql oracle triggers oracle11g

当主表中发生更改时,我使用触发器将旧值和新值插入审计跟踪表。

create or replace TRIGGER audit_trg
  BEFORE UPDATE ON Employee
  FOR EACH ROW
BEGIN
  IF( UPDATING( 'E_AGE' ) )
  THEN
  IF(NVL(:OLD.E_AGE,0)!=NVL(:new.E_AGE,0))
  THEN
   INSERT INTO AUDIT_TRAIL( ID,PRIMARY_KEY,TABLENAME,COLUMNNAME,OLDVALUE,NEWVALUE,UPDATEDDATETIME,UPDATEDBY ,DESCRIPTION)
      VALUES(AUDIT_TRAIL_SEQ.NEXTVAL,:new.ID,'Employee','E_AGE',NVL(:OLD.E_AGE,0),:new.E_AGE,sysdate, :new.UPDATEDBY,:new.DESCRIPTION );
  END IF;
  END IF;
END;

但是,只有在前一个值为空时才会向Audit trail table插入任何值。

2 个答案:

答案 0 :(得分:1)

尝试

if nvl( :old.e_age, 0 ) != nvl( :new.e_age, 0 )

您希望从比较的两边摆脱NULL

编辑:这是我对触发器的测试。第1行和第4行是"没有变化"条件和Trail列应保持不变,且值为零。其余表示更改:从一个值到另一个值(2),从值到NULL(3)以及从NULL到值(5)。对于这些行,Trail值应为OldAge / NewAge值。他们是。

drop table TestEmp;
create table TestEmp(
    id      int,
    e_age   int,
    NewVal  int,
    Trail   int default 0
);

insert into TestEmp( id, e_age, NewVal )
    select  1, 10, 10 from dual union all
    select  2, 10,  8 from dual union all
    select  3, 10, null from dual union all
    select  4, null, null from dual union all
    select  5, null, 10 from dual;

create or replace TRIGGER audit_trg
  BEFORE UPDATE ON TestEmp
  FOR EACH ROW
BEGIN
    IF UPDATING( 'E_AGE' ) THEN
        IF NVL( :OLD.e_age, 0 ) != NVL( :new.e_age, 0 ) THEN
            :new.Trail := :new.e_age;
        END IF;
    END IF;
END;
/
select * from TestEmp;
update TestEmp set e_age = NewVal;
select * from TestEmp;

更新前:

ID   E_AGE NewVal TRAIL
 1      10     10     0
 2      10      8     0
 3      10 <null>     0
 4  <null> <null>     0
 5  <null>     10     0

更新后:

ID   E_AGE NewVal TRAIL
 1      10     10     0
 2      10      8     8
 3  <null> <null> <null>
 4  <null> <null>     0
 5      10     10    10

因此,为第2,3,5行输入了if语句 - 正如预期的那样。

答案 1 :(得分:0)

我遇到了类似的问题,在更新触发器没有创建任何历史记录时,值从null更改为值。我的逻辑适用于任何变化,除了空值

如果nvl(:old.price,null)&lt;&gt; nvl(:new.price,null)然后      插入bla bla ....         价值观(......);    结束如果;