2015-01-29 3 views
0

마스터 테이블에서 변경이 발생하면 트리거를 사용하여 감사 내역 테이블에 이전 값과 새 값을 삽입합니다.이전 값이 null 인 경우 트리거가 실행되지 않음

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; 

그러나 이전 값이 null 인 경우에만 감사 내역 테이블에 값을 삽입하지 않습니다.

답변

1

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

당신은 비교의 양쪽에서 NULL 제거하려는 시도합니다.

편집 : 이것은 내 방아쇠 테스트입니다. 행 1과 4는 "변경 없음"조건이며 트레일 열은 변경되지 않고 0으로 유지됩니다. 나머지는 하나의 값에서 다른 값으로 (2), 값을 NULL (3)으로, NULL에서 값 (5)으로 변경을 나타냅니다. 이 행의 경우 트레일 값은 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 

가 그래서 if 문이 행 2, 3 입력 된, 5 - 예상대로.

+0

시도했지만 여전히 값을 삽입하지 않습니다. –

+0

무엇을 말 할 지 모르겠습니다. 내 테스트를 참조하십시오. – TommCatt

+0

가능성 : (1) NULL 값을 0으로 업데이트하면 조건은 FALSE로 평가되고 감사 레코드가 삽입되지 않습니다. (2) 여러 세션을 사용하는 경우 감사 로그를 쿼리하기 전에 업데이트 트랜잭션이 커밋되었는지 확인하십시오. 트리거의 삽입은 업데이트와 동일한 트랜잭션에서 발생합니다. –

0

업데이트 트리거가 값이 null에서 값으로 변경 될 때 기록을 만들지 않기 전에 비슷한 문제가 있습니다. 내 로직은 NULL의 값을 제외한 모든 변경 작동

경우 NVL (: old.price, NULL) <> NVL (: new.price, NULL) BLA 즐에 삽입 한 다음 .... 값 (......); end if;

+1

흠 ... 내 대답처럼 보이지 않습니까? – kleopatra

+1

'NVL (x, NULL)'은 무의미한 연산입니다 - 단지'x'를 말하는 것과 같습니다. 두 표현식 중 하나가 NULL이면 부등호는 여전히 FALSE로 평가됩니다. 테스트를 수행하기 위해 NULL이 아닌 표현식을 사용하려고합니다. 'NVL (x, 0)'. –

+0

지금 작동 중입니다. 감사 – user4826005

관련 문제