您当前的位置: 首页 >  oracle

Oracle变异表解决方法--ORA-04091错误

发布时间:2017-05-31 21:08:45 ,浏览量:0

Oracle变异表解决方法--ORA-04091错误

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

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

对表进行DELETE,UPDATE,INSERT操作时,所操作的表就变成了变异表,对表的行级(FOR EACH ROW)触发器中不能对该表进行DML操作。这时可以使用两个方法解决。

[@more@]

1、采用自治事务pragma autonomous_transaction解决。

下面给出一个使用自治事务解决ORA-04091错误的示例:

CREATE OR REPLACE TRIGGER SCOTT.TRG_UPDATE_EMP

  AFTER UPDATE ON SCOTT.EMP

  FOR EACH ROW

DECLARE

  V_NUM NUMBER;

BEGIN

  SELECT COUNT(1) INTO V_NUM FROM SCOTT.EMP T WHERE DEPTNO = :NEW.DEPTNO;

  IF V_NUM > 2 THEN

    RAISE_APPLICATION_ERROR(-20001, V_NUM);

  END IF;

END;

执行更新操作报错ORA-04091:

SYS@lhrdb> UPDATE SCOTT.EMP SET SAL=0 ;

UPDATE scott.emp set sal=0

             *

ERROR at line 1:

ORA-04091: table SCOTT.EMP is mutating, trigger/function may not see it

ORA-06512: at "SCOTT.TRG_UPDATE_EMP", line 4

ORA-04088: error during execution of trigger 'SCOTT.TRG_UPDATE_EMP'

这里加上自治事务后可以解决该问题:

CREATE OR REPLACE TRIGGER SCOTT.TRG_UPDATE_EMP

  AFTER UPDATE ON SCOTT.EMP

  FOR EACH ROW

DECLARE

  PRAGMA AUTONOMOUS_TRANSACTION;

  V_NUM NUMBER;

BEGIN

  SELECT COUNT(1) INTO V_NUM FROM SCOTT.EMP T WHERE DEPTNO = :NEW.DEPTNO;

  IF V_NUM > 2 THEN

    RAISE_APPLICATION_ERROR(-20001, V_NUM);

  END IF;

END;

再次执行:

SYS@lhrdb> UPDATE SCOTT.EMP SET SAL=0 ;

UPDATE SCOTT.EMP SET SAL=0

             *

ERROR at line 1:

ORA-20001: 4

ORA-06512: at "SCOTT.TRG_UPDATE_EMP", line 7

ORA-04088: error during execution of trigger 'SCOTT.TRG_UPDATE_EMP'

------------------------------------------------ 再给出一个例子

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

[sql]  view plain  copy
  1. SQL> create table tr_table as select * from emp;  
  2.   
  3. 表已创建。  
  4.   
  5. SQL> edit  
  6. 已写入 file afiedt.buf  
  7.   
  8.   1  create or replace trigger tr_test  
  9.   2  after update on emp  
  10.   3  for each row  
  11.   4  begin  
  12.   5     update tr_table t set t.sal = (select sal from emp where empno=t.empno and empno=:new.empno);  
  13.   6* end;  
  14. SQL> /  
  15.   
  16. 触发器已创建  
  17.   
  18. SQL> update emp set sal=3700 where empno=7788;  
  19. update emp set sal=3700 where empno=7788  
  20.        *  
  21. 第 1 行出现错误:  
关注
打赏
1688896170
查看更多评论

暂无认证

  • 0浏览

    0关注

    108476博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.1733s