錯誤"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原表,最好是把此邏輯放到觸發器外面,另寫存儲過程實現原有功能


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM