oracle触发器和事物

关于触发器详细描述见下面这个大牛的博客

www.cnblogs.com/huyong/archive/2011/04/27/2030466.html


编写触发器时,需要注意以下几点:

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触发器、系统触发器) 的语法格式和作用有较大区别。


关于“在触发器主体中调用的任何过程、函数,都不能使用事务控制语句。” 这个可以区分一下,如果调用的过程中声明的是“自治事物”是可以调用的。


创建如下三张表,一个触发器和两个过程

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;
/


第一步触发器中的“

  -- pro_t_test2(:old.id,:old.tname);
  --rollback;
”这两行是没有注释的掉。

虽然这个触发器可以创建成功,但是在insert操作的时候会报错ora-04092。

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
 
SQL>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-无-为-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值