zoukankan      html  css  js  c++  java
  • 错误"ORA-04091: table is mutating, trigger/function may not see it"的原因以及解决办法

    错误的原因
    该错误是在编写trigger时常遇到的问题,其根本原因是由于对本表的操作造成的。对于使用了for each row 的触发器,做了DML操作(delete,update,insert),还没有提交时,是不允许其他PL/SQL对本表的DML操作,以及查询,因为此时数据不一致。

    解决办法:

    1 自治事务

    自治事物的概念:就是在subprogram里进行事物的提交不影响主程序的事务,同样主程序的提交或回滚都不影响子程序的commit,即子程序的事物和主程序的事物完全独立。
    示例:

    [java] view plain copy
     
    1. CREATE OR REPLACE TRIGGER TR_T  
    2.   AFTER DELETE ON T  
    3.   FOR EACH ROW  
    4.   DECLARE V_COUNT NUMBER;  
    5.   PRAGMA AUTONOMOUS_TRANSACTION;  
    6.   BEGIN  
    7.      INSERT INTO T VALUES(:OLD.ID,:OLD.MC,SYSDATE);  
    8. END TR_DEL_CABLE;  

    PRAGMA AUTONOMOUS_TRANSACTION:就是对自治事务的声明

    要注意的就是:自治事务必须慎用,因为一个DML可能会产生许多个独立的事物,这很容易引发死锁,ASKTOM上对AUTONOMOUS_TRANSACTION的看法是:唯一的用途就是作审计日志,其他一概不该使用。

    2 网上还有人给出了另一种解决办法:建临时表

    新建了与要操作的表结构完全相同的临时表,使得在本表上的触发器读写建好的临时表,再用临时表上的触发器写回本表,也倒是个办法,但是不是最好的,过于繁琐

    治本之法Oracle的绝大多数类型的trigger都不支持dml原表,最好是把此逻辑放到触发器外面,另写存储过程实现原有功能

  • 相关阅读:
    [CF1342D] Multiple Testcases
    [CF448D] Multiplication Table
    [CF459C] Pashmak and Buses
    [CF766E] Mahmoud and a xor trip
    [CF35E] Parade
    [CF15C] Industrial Nim
    [CF9D] How many trees?
    [CF19B] Checkout Assistant
    [CF22D] Segments
    [CF21D] Traveling Graph
  • 原文地址:https://www.cnblogs.com/soundcode/p/6171047.html
Copyright © 2011-2022 走看看