大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
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
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/157728.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...