1、初始目標
在對表h1插入一條數據時,同時插入一條重復的數據(只有主鍵不同)
2、在PL/SQL里New一個Trigger或者手動敲入代碼
先說明一下,表h1包括4列ID、C1、C2、C3
create or replace trigger Trigger_Testafter insert on h1for each row
declare--variables
begininsert into h1 values(:new.C1, :new.C2, :new.C3, :new.ID);
end Trigger_Test;
3、F8編譯通過,新建一個窗口執行insert窗口,測試trigger是否有效,用了一個名為sequence_test的序列:
insert into h1 values('aa','bb','cc',sequence_test.nextval);
報錯:表h1發生了變化,觸發器/函數不能讀。
4、網上搜的說法是“觸發器不能修改觸發表的數據,除非使用自治事務”,OK那就用自治事務:
declare--variables
//改為:
declarepragma autonomous_transaction;
再試報錯:等待資源時檢測到死鎖。仔細一查,哦原來是目標有問題,Insert連著Insert,無限循環,不是資源死鎖就是內存不足或者棧溢出。
5、目標更新為:在對表h1插入一條數據時,同時插入一條相同的數據到歷史表里,把trigger里的insert修改為:
insert into h1_history values(:new.C1, :new.C2, :new.C3, :new.ID);
再跑又報錯:檢測到活動的自治事務處理,已經回退。
6、網上接著搜,說是有事務沒提交。其實這是之前目標設定有問題,觸發器一般不會修改觸發表,用了自治事務,就要commit;如果是插入歷史表,可以都不加。
declarepragma autonomous_transaction;commit;delete from h1 where ID = 1;commit;//如果不操作觸發表,則可以去掉自治事務的這一串聲明
declareinsert into h1_history values(:new.C1, :new.C2, :new.C3, :new.ID);
7、小結
- Trigger在修改其他表(非觸發表)的時候,最方便,直接像寫存儲過程即可;
- 若要使用Trigger修改觸發表的數據,需要配合使用自治事務并commit,比較麻煩;
- 對新操作的記錄本身(比如新Insert/Update/Delete的數據),無法做修改,并且如果強行修改的話,既不會報錯,也沒有效果。