2009-12-07 28 views

回答

4

因爲DML可能已經基於set,影響表中的多行。事實上,由於SQL是正確設置的,應該是通常的情況。因此,語句級別觸發器無法確定您的意思是:OLD和哪些:NEW值。

6

因爲這可能是該語句插入/刪除/更新多行的情況。所以沒有新的舊的列。

例子:

update FOO set a = 12 where b = 9; 

或者:

delete from FOO where b = 9; 

或者:

insert into FOO (a, b) select 12, x from BAR; 

如果FOO表有一個語句觸發器,在這三句話是沒有辦法告訴你是否在無,單行或多行上操作。

0

如前所述,語句級別觸發器可以用於一到多行更改,因此:new和:old不可用。

如果您需要跟蹤:新值和舊值,並且需要在語句觸發器訪問它們,則可以創建一個行級觸發器來存儲供語句級使用的新值和舊值。這是我們

包之前已經解決了這個問題的一種方法:

create or replace package table_trigger_helper is 

    subtype subtype_rowtype is table_name$rowtype; 
    type table_rowtype is table of subtype_rowtype; 

    v_old table_rowtype := table_rowtype(); 
    v_new table_rowtype := table_rowtype(); 

end table_trigger_helper; 
/

行級觸發器:

create or replace trigger row_level_trigger_name 
    after insert or delete or update 
    on table_name 
    for each row 
declare 

    r_old table_trigger_helper.table_rowtype := NULL; 
    r_new table_trigger_helper.table_rowtype := NULL; 
    i pls_integer; 

begin 

if update or deleting then 
    r_old.column_one := :old.column_one 
    ... 
end if; 

if update or inserting then 
    r_new.column_one := :new.column_one 
end if; 

    table_trigger_helper.v_old.extend(); 
    table_trigger_helper.v_new.extend(); 
    i := table_trigger_helper.v_old.last; 

    table_trigger_helper.v_old(i) := r_old; 
    table_trigger_helper.v_new(i) := r_new; 
end row_level_trigger_name; 
/ 

語句級觸發器:

create or replace trigger statement_level_trigger_name 
after insert or delete or update 
on table_name 
declare 
begin 
    --process through your new and old records; 
    --table_trigger_helper.v_old 
    --table_trigger_helper.v_new 
end statement_level_trigger_name; 
/