您的位置:首页 > 其它

ORA-04091错误原因与解决方法

2014-09-26 10:40 453 查看
最近工作中写了一触发器报错:ORA-04091:table XX is mutating, trigger/function may not see it。

下面通过官方文档及网友提供资料分析一下错误原因及解决方法:

1.查看oracle官方文档:



原因:触发器(或者被语句中引用的用户自定义PL/SQL函数)视图去查询(或修改)一个被另一语句修改而触发的表。

解决方法:重写触发器(或函数)避免读该表。

2.根据错误原因我们写如下触发器,重现错误:

使用scott方案,创建一下表、触发器:

[sql] view
plaincopy

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语句如下:

[sql] view
plaincopy

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语句如下:

[sql] view
plaincopy

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] view
plaincopy

SQL> update emp set sal=3800 where empno=7788;

已更新 1 行。

SQL> commit;

提交完成。

[sql] view
plaincopy

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行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: