2014-12-02 118 views
0

我正在編寫一個簡單的觸發器,它應該只發送一條消息,其中包含更新的行數以及Gender的舊值和Gender的更新值。當我運行一個更新,但是我得到的錯誤是表變異,表可能無法看到它,但我不完全確定爲什麼。Oracle突變觸發器

觸發

create or replace trigger updatePERSONS 
after update 
on PERSONS 
for each row 
declare 
n int; 
oldGender varchar(20):= :OLD.Gender; 
newGender varchar(20):= :NEW.Gender; 

begin 
select Count(*) 
into n 
from PERSONS; 

if (oldGender != newGender) then 
dbms_output.put_line('There are now '|| n || ' rows after update. Old gender: ' || oldGender 
|| ', new Gender: ' || newGender); 

end if; 
End; 

`

我知道它做的select語句開始後,但怎麼回事,我會得到的行數?

+0

的問題是有與'SELECT COUNT(*)'聲明,在一個行級觸發器,你不能指代在其上創建觸發器的表。在這裏,您已經在PERSONS表上創建了觸發器,並且您試圖從觸發器內的同一個表中獲取數據,這在Oracle中是不允許的。 – San 2014-12-02 19:36:24

+0

好吧,我想的很多。我應該把它放在哪裏?或者我還能如何獲得計數? – user3587186 2014-12-02 19:40:14

回答

2

正如@San所指出的,persons上的行級觸發器通常不能查詢persons表。

您需要兩個觸發器,一個可以查看舊性別和新性別的行級觸發器以及一個可以進行計數的語句級觸發器。如果你使用11g,你也可以創建一個具有行級和語句級塊的複合觸發器。

create or replace trigger trg_stmt 
    after update 
    on persons 
declare 
    l_cnt integer; 
begin 
    select count(*) 
    into l_cnt 
    from persons; 

    dbms_output.put_line('There are now ' || l_cnt || ' rows.'); 
end; 

create or replace trigger trg_row 
    after update 
    on persons 
    for each row 
begin 
    if(:new.gender != :old.gender) 
    then 
    dbms_output.put_line('Old gender = ' || :old.gender || ', new gender = ' || :new.gender); 
    end if; 
end;