我是靠谱客的博主 微笑钢铁侠,最近开发中收集的这篇文章主要介绍Oracle触发器报错table xxxx is mutating,trigger/function may not see it,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

写了一个数据更新的触发器 , 但是写完编译没问题 , 一使用就报错. 然后在PLsql中调试了一下,报了table xxxx is mutating,trigger/function may not see it这个错, 上网查了原来是这样.


1.

对于after 类型的 for each row 级别的triggers,不论哪种insert语句触发了trigger,

都不允许在 trigger 中访问本trigger所依赖的table

2.
对于before 类型的 for each row 级别的triggers,如果使用 insert into ... values 语句触发此trigger ,
则在trigger 中访问本table没有问题;但如果使用 insert into select .. from 语句触发此trigger ,
则在trigger 中访问本table就报ora-04091错误;


明明逻辑都正确,其中的sql语句单独拿出来也能用,调试的时候就是卡在那个地方.无语,真浪费时间啊...


只要按上面这两个规则,就会正常。

2017.3.24修改:
今天又写了一个触发器,如果update A表的某个字段触发这个触发器,里面的逻辑还是要查询所依赖的A表,又导致table xxxx is mutating,trigger/function may not see it这个错误。
就算按照上面的两个规则也不行,在网上查到可以用PRAGMA AUTONOMOUS_TRANSACTION; 
就可以执行成功,格式如下:
(以下转自http://blog.csdn.net/tw7752/article/details/44624437)
create or replace trigger tr_test  
after insert   
on test  
for each row  
declare  
PRAGMA AUTONOMOUS_TRANSACTION;  
begin  
   update test set column2=123 where column1=:new.column1  
end tr_test;  

AUTONOMOUS_TRANSACTION是指在function,procedure,trigger等subprograms中对事务进行自治管理,当在别的pl/sql block里取调用这些subprograms的时候这些subprograms并不随着父pl/sql block的失败而回滚,而是自己管自己commit;

注意慎用AUTONOMOUS_TRANSACTION。一个DML可能触发很多次触发器,因此产生了大量独立的事务,很容易产生死锁。 ASKTOM上对AUTONOMOUS_TRANSACTION的看法是:唯一的用途就是作审计日志,其他一概不该使用。 有人建议是取消使用触发器,把你的业务逻辑写到存储过程去。

PS:虽然这样执行成功,但不知后续会产生什么后果,是不是很容产生死锁等,以后会持续更新。如果好长时间不更就说明是问题不大的。

3月28日:因为业务上的原因没有采用PRAGMA AUTONOMOUS_TRANSACTION这个方式,也不用触发器了,代码都写到项目里。但是感觉用起来还是没问题的。

最后

以上就是微笑钢铁侠为你收集整理的Oracle触发器报错table xxxx is mutating,trigger/function may not see it的全部内容,希望文章能够帮你解决Oracle触发器报错table xxxx is mutating,trigger/function may not see it所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部