ORA-04091错误原因与解决方法
最近工作中写了一触发器报错:ORA-04091:table XX is mutating, trigger/function may not see it。
下面通过官方文档及网友提供资料分析一下错误原因及解决方法:
1.查看oracle官方文档:

原因:触发器(或者被语句中引用的用户自定义PL/SQL函数)视图去查询(或修改)一个被另一语句修改而触发的表。
解决方法:重写触发器(或函数)避免读该表。
2.根据错误原因我们写如下触发器,重现错误:
使用scott方案,创建一下表、触发器:
- SQL> create table tr_table as select * from emp;
- 表已创建。
- SQL> edit
- 已写入 file afiedt.buf
- 1 create or replace trigger tr_test
- 2 after update on emp
- 3 for each row
- 4 begin
- 5 update tr_table t set t.sal = (select sal from emp where empno=t.empno and empno=:new.empno);
- 6* end;
- SQL> /
- 触发器已创建
- SQL> update emp set sal=3700 where empno=7788;
- update emp set sal=3700 where empno=7788
- *
- 第 1 行出现错误:
- <span style="color:#ff0000;">ORA-04091: 表 SCOTT.EMP 发生了变化, 触发器/函数不能读它
- </span>ORA-06512: 在 "SCOTT.TR_TEST", line 2
- ORA-04088: 触发器 'SCOTT.TR_TEST' 执行过程中出错
3.原因分析:
在Oracle中执行DML语句的时候是需要显示进行提交操作的。当我们进行插入的时候,会触发触发器执行对触发器作用表和扩展表的种种操作,但是这个时候触发器和插入语句是在同一个事务管理中的,因此在插入语句没有被提交的情况下,我们无法对触发器作用表进行其他额外的操作。如果执行其他额外的操作则会抛出如上异常信息。
4.解决方案:
1) 我们知道,出错的原因是因为触发器和DML语句在同一事务管理中,所以方案一便是将触发器和DML语句分成两个单独的事务处理。这里可以使用Pragma autonomous_transaction; 告诉Oracle触发器是自定义事务处理。
SQL语句如下:
- create or replace trigger tr_test
- after update on emp
- for each row
- declare
- pragma autonomous_transaction;
- begin
- update tr_table t set t.sal = (select sal from emp where empno=t.empno and empno=:new.empno);
- commit; --此处需要显示提交
- end;
注:以上语句并不能实时获得更新的值。。。原因是我们在update emp表后还没来得及提交sal就触发了触发器,这个时候获取到的只能是老的sal值。
2) 在Oracle Trigger中有:new,:old两个特殊变量,当触发器为行级触发器的时候,触发器就会提供new和old两个保存临时行数据的特殊变量,我们可以从俩个特殊的变量中取出数据执行扩张表的DML操作。
SQL语句如下:
- create or replace trigger tr_test
- after update on emp
- for each row
- begin
- update tr_table t set t.sal = :new.sal;
- end;
- /
5. 再次插入数据:
- SQL> update emp set sal=3800 where empno=7788;
- 已更新 1 行。
- SQL> commit;
- 提交完成。
- SQL> select * from tr_table;
- EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
- ---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
- 7369 SMITH CLERK 7902 17-12月-80 800 20
- 7499 ALLEN SALESMAN 7698 20-2月 -81 1800 300 30
- 7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30
- 7566 JONES MANAGER 7839 02-4月 -81 2975 20
- 7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30
- 7698 BLAKE MANAGER 7839 01-5月 -81 2850 30
- 7782 CLARK MANAGER 7839 09-6月 -81 2450 10
- <span style="BACKGROUND-COLOR: #009900">7788 SCOTT ANALYST 7566 19-4月 -87 3800 20
- </span> 7839 KING PRESIDENT 17-11月-81 5000 10
- 7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30
- 7876 ADAMS CLERK 7788 23-5月 -87 1100 20
- EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
- ---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
- 7900 JAMES CLERK 7698 03-12月-81 950 30
- 7902 FORD ANALYST 7566 03-12月-81 3000 20
- 7934 MILLER CLERK 7782 23-1月 -82 1300 10
- 已选择14行。
ORA-04091错误原因与解决方法的更多相关文章
- coreseek常见错误原因及解决方法
coreseek常见错误原因及解决方法 Coreseek 中文全文检索引擎 Coreseek 是一款中文全文检索/搜索软件,以GPLv2许可协议开源发布,基于Sphinx研发并独立发布,专攻中文搜索和 ...
- /usr/bin/ld: cannot find -lc错误原因及解决方法
问题解决 我在执行如下命令的时候,出现了错误. gcc -o main main.c -static -L. –lmylib Linux环境下gcc静态编译/usr/bin/ld: cannot fi ...
- SpringBoot+Shiro引起事务失效、错误原因、解决方法
一.问题今天发现用户注册的Service的事务并没有起到作用,再抛出一个RuntimeException后,并没有发生回滚,下面是调试步骤: 1.检查数据库的引擎是否是innoDB 2.启动类上是否加 ...
- httpclient org.apache.http.NoHttpResponseException: host:端口 failed to respond 错误原因和解决方法
原因:httpclient 之前与服务端建立的链接已经失效(例如:tomcat 默认的keep-alive timeout :20s),再次从连接池拿该失效链接进行请求时,就会保存. 解决方法:官方链 ...
- SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape错误原因及解决方法
用Python打开文件: with open('C:\Users\PINPIN\test\file1.txt','r') as f2: pass 运行后直接就报错了: File "<i ...
- iBatis查询时报"列名无效"或"找不到栏位名称"无列名的错误原因及解决方法
iBatis会自动缓存每条查询语句的列名映射,对于动态查询字段或分页查询等queryForPage, queryForList,就可能产生"列名无效".rs.getObject(o ...
- c++ std::sort函数调用经常出现的invalidate operator<错误原因以及解决方法
在c++编程中使用sort函数,自定义一个数据结构并进行排序时新手经常会碰到这种错误. 这是为什么呢?原因在于什么?如何解决? 看下面一个例子: int main(int, char*[]) { st ...
- 移动端页头推荐配置 出现找不到favicon.ico错误原因和解决方法
favicon 在未指定 favicon 时,大多数浏览器会请求 Web Server 根目录下的 favicon.ico .为了保证 favicon 可访问,避免404,必须遵循以下两种方法之一: ...
- javascript中出现identifier starts immediately after numeric literal错误原因以及解决方法
javascript遇到参数是字符型和数字型组合的参数就会出现这种错误,例如alert(1);可以正確輸出alert(str);就會報錯alert("str");可以正確輸出.
随机推荐
- Python 2.7 闭包的局限
想法源自:http://stackoverflow.com/questions/141642/what-limitations-have-closures-in-python-compared-to- ...
- hive分区partition(动态和静态分区混合使用; partition的简介)
分区是hive存放数据的一种方式.将列值作为目录来存放数据,就是一个分区.这样where中给出列值时,只需根据列值直接扫描对应目录下的数据,不扫面其他不关心的分区,快速定位,查询节省大量时间.分动态和 ...
- mongo 写分析
写操作 复制集 mongo所有的节点都是写入到primary节点,同时写入oplog,secondary 节点会持续的从primary节点上复制oplog的信息,然后根据oplog写数据.second ...
- Android常用的编译命令
1.make -jX X表示数字,这个命令将编译Android系统并生成镜像,XX表示可以使用到的CPU核数,这在配置好的电脑上特别有用,公司的16核ubuntu服务器执行make -j16只要不到2 ...
- iOS学习笔记--Quartz2D
Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统. Quartz 2D能完成的工作: 1. 绘制图形 : 线条\三角形\矩形\圆\弧等 2. 绘制文字 3. 绘制\生成图片(图像) 4 ...
- 获取客户信息SQL
/*取客户信息SQL*/ --客户信息 SELECT hou.name 业务实体, hca.account_number 客户编号, hp.party_name 客户名称, arp_addr_pkg. ...
- 解决Setting property 'source' to 'org.eclipse.jst.jee.server的问题
对于这个问题,我相信我的方法已经能帮90%的人解决了! 当你用Eclipse运行web项目的时候,你就会看到控制台出现: WARNING: [SetPropertiesRule]{Server/Ser ...
- FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-TU
===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...
- 并发计算模型BSP与SEDA
1 BSP批量同步并行计算 BSP(Bulk Synchronous Parallel)批量同步并行计算用来解决并发编程难的问题.名字听起来有点矛盾,又是同步又是并行的.因为计算被分组成一个个超 ...
- 会声会影小成果分享(那段青春岁月)——校学习部宣传视频制作&生日祝福
大二的时候在校学习部当副部长,没有给干事们带去好的工作经验和管理方法,我净在折腾新媒体方面的东西,很惭愧的说,那时候申请了一个微信的公众号(HGXXB1314),我那时候以为自己很叼,最后是发现自己装 ...