2014-10-20 86 views
0

我有一個簡單的表:如何知道更新語句更新哪些列?

CREATE TABLE "TEST1" 
(
    "COLUMN1" VARCHAR2(20 BYTE), 
    "COLUMN2" CLOB, 
    "COLUMN3" RAW(16), 
    "COLUMN4" BLOB 
) 

現在我還想寫它監視的更新,其中包含實際變化觸發。

我嘗試這樣做:

CREATE OR REPLACE TRIGGER "TEST1_TRIGGER1" 
AFTER UPDATE ON "TEST1" 
FOR EACH ROW 
begin 
    dbms_output.put_line ('test1_trigger1'); 
    if :old.column1 <> :new.column1 then 
    dbms_output.put_line ('column1 differs'); 
    end if; 
    if :old.column2 <> :new.column2 then 
    dbms_output.put_line ('column2 differs'); 
    end if; 
    if :old.column3 <> :new.column3 then 
    dbms_output.put_line ('column3 differs'); 
    end if; 
    if :old.column4 <> :new.column4 then 
    dbms_output.put_line ('column4 differs'); 
    end if; 
    NULL; 
END; 

這引發以下錯誤:

 
Error(16,19): PLS-00306: wrong number or types of arguments in call to '!=' 

的問題是,Oracle無法比較BLOB。

我該如何避免這個問題?我如何知道更新更新的列?

回答

3

可以使用when updating predicate

... 
begin 
    dbms_output.put_line ('test1_trigger1'); 
    if updating ('column1') then 
    dbms_output.put_line ('column1 differs'); 
    end if; 
    if updating ('column2') then 
    dbms_output.put_line ('column2 differs'); 
    end if; 
    if updating ('column3') then 
    dbms_output.put_line ('column3 differs'); 
    end if; 
    if updating ('column4') then 
    dbms_output.put_line ('column4 differs'); 
    end if; 
end; 

例如:

SQL> insert into test1 values ('A', 'B', 'AA', null); 
SQL> update test1 set column1 = 'X', column2 = 'Y', column3 = 'FF'; 

test1_trigger1 
column1 differs 
column2 differs 
column3 differs 
+0

是'CASE'不如'IF'。 ;-) – ceving 2014-10-20 09:45:07

2

如果列包含在更新語句中的WHEN UPDATING(column)謂詞返回TRUE,即使價值實際上並沒有改變。如果你想監視實際的變化,那麼你可以使用提供的軟件包:

CREATE OR REPLACE TRIGGER test1_trigger1 
AFTER UPDATE ON test1 
FOR EACH ROW 
begin 
    if ( (:old.column1 is null and :new.column1 is not null) 
    or (:old.column1 is not null and :new.column1 is null) 
    or (:old.column1 <> :new.column1)) 
    then 
    dbms_output.put_line ('column1 differs'); 
    end if; 
    if ( (:old.column2 is null and :new.column2 is not null) 
    or (:old.column2 is not null and :new.column2 is null) 
    or (dbms_lob.compare(:old.column2, :new.column2) <> 0)) 
    then 
    dbms_output.put_line ('column2 differs'); 
    end if; 
    if (utl_raw.compare(:old.column3, :new.column3) <> 0) then 
    dbms_output.put_line ('column3 differs'); 
    end if; 
    if ( (:old.column4 is null and :new.column4 is not null) 
    or (:old.column4 is not null and :new.column4 is null) 
    or (dbms_lob.compare(:old.column4, :new.column4) <> 0)) then 
    dbms_output.put_line ('column4 differs'); 
    end if; 
end; 
+0

好點...我錯過了「中包含實際變化」的位。 – 2014-10-20 11:59:59