Oracle觸發器和事務
oracle觸發器和事務
2015年11月24日 14:16:43 it_taojingzhan 閱讀數:320
編寫觸發器時,需要注意以下幾點:
l 觸發器不接受引數。
l 一個表上最多可有12個觸發器,但同一時間、同一事件、同一型別的觸發器只能有一個。並各觸發器之間不能有矛盾。
l 在一個表上的觸發器越多,對在該表上的DML操作的效能影響就越大。
l 觸發器最大為32KB。若確實需要,可以先建立過程,然後在觸發器中用CALL語句進行呼叫。
l 在觸發器的執行部分只能用DML語句(SELECT、INSERT、UPDATE、DELETE),不能使用DDL語句(CREATE、ALTER、DROP)。
l 觸發器中不能包含事務控制語句(COMMIT,ROLLBACK,SAVEPOINT)。因為觸發器是觸發語句的一部分,觸發語句被提交、回退時,觸發器也被提交、回退了。
l 在觸發器主體中呼叫的任何過程、函式,都不能使用事務控制語句。
l 在觸發器主體中不能申明任何Long和blob變數。新值new和舊值old也不能向表中的任何long和blob列。
l 不同型別的觸發器(如DML觸發器、INSTEAD OF觸發器、系統觸發器)的語法格式和作用有較大區別。
關於“在觸發器主體中呼叫的任何過程、函式,都不能使用事務控制語句。” 這個可以區分一下,如果呼叫的過程中宣告的是“自治事物”是可以呼叫的。
建立如下三張表,一個觸發器和兩個過程
[html] view plaincopy
- create table t_test(id int,tname varchar2(20));
- create table t_test1(id int,tname varchar2(20));
- create table t_test2(id int,tname varchar2(20));
- create or replace trigger tr_t_test
- after insert
- on t_test
- FOR EACH ROW
- DECLARE
- i int;
- begin
- i :=1;
- pro_t_test1(:NEW.id,:NEW.tname);
- -- pro_t_test2(:old.id,:old.tname);
- --rollback;
- end;
- /
- create or replace procedure pro_t_test1(vid int, vname varchar2)
- is
- Pragma Autonomous_transaction;
- begin
- insert into t_test1 values(vid,vname);
- commit;
- end;
- /
- create or replace procedure pro_t_test2(vid int, vname varchar2)
- is
- begin
- insert into t_test2 values(vid,vname);
- commit;
- end;
- /
第一步觸發器中的“
[html] view plaincopy
- -- pro_t_test2(:old.id,:old.tname);
- --rollback;
”這兩行是沒有註釋的掉。
雖然這個觸發器可以建立成功,但是在insert操作的時候會報錯ora-04092。
[html] view plaincopy
- SQL> insert into t_test values(1,'a');
- insert into t_test values(1,'a')
- ORA-04092: cannot COMMIT in a trigger
- ORA-06512: at "YJQF.PRO_T_TEST2", line 5
- ORA-06512: at "YJQF.TR_T_TEST", line 7
- ORA-04088: error during execution of trigger 'YJQF.TR_T_TEST'
- SQL> commit;
- Commit complete
- SQL> select count(*) from t_test;
- COUNT(*)
- ----------
- 0
- SQL> select count(*) from t_test1;
- COUNT(*)
- ----------
- 1
- SQL> select count(*) from t_test2;
- COUNT(*)
- ----------
- 0
- SQL>
- SQL> insert into t_test values(1,'a');
- insert into t_test values(1,'a')
- ORA-04092: cannot ROLLBACK in a trigger
- ORA-06512: at "YJQF.TR_T_TEST", line 8
- ORA-04088: error during execution of trigger 'YJQF.TR_T_TEST'
- SQL> commit;
- Commit complete
- SQL> select count(*) from t_test;
- COUNT(*)
- ----------
- 0
- SQL> select count(*) from t_test1;
- COUNT(*)
- ----------
- 2
- SQL> select count(*) from t_test2;
- COUNT(*)
- ----------
- 0
- SQL>
這兩條insert雖然失敗了,但是還是寫到了t_test1表中了,在pro_t_test1上是有commit的,從這個可以看出“自主事物”是完全獨立的。
在你的主事務中,你可以選擇能夠從其他事務中進行呼叫的獨立事物。自治事務可以提交或回滾其修改而不影響呼叫它的主事務。
將這兩行後註釋掉後,插入就成功了。
SQL> insert into t_test values(1,'a');
1 row inserted
SQL> commit;
Commit complete
SQL> select count(*) from t_test;
COUNT(*)
----------
1
SQL> select count(*) from t_test1;
COUNT(*)
----------
3
SQL> select count(*) from t_test2;
COUNT(*)
----------
0
https://blog.csdn.net/it_taojingzhan/article/details/50012161