我有一张简单的表格:
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无法比较BLOBS。
我该如何避免这个问题?如何知道更新更新的列?
答案 0 :(得分: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
答案 1 :(得分:2)
如果列包含在update语句中,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;