2013年1月18日調試觸發器“表發生了變化,觸發器或函數不能讀它”的出現原因,以及解決方案


1、異常出現的場景.

:在使用Hibernate做為項目持久層的情況下,需要對某一張表進行一個擴展,擴展操作便是在該表上創建一個觸發器。將表中的數據讀入到其他表中。

SQL語句如下:

 

drop table tr_table;   
  
    create table tr_table(  --觸發器作用表   
    tab_id number primary key,   
    tab_name varchar2(30) NOT NULL  
    )   
  
    create table ts_table as select * from tr_table; --提供擴展功能的表   
               
    --定義的觸發器,在tr_table表插入和更新數據之后向ts_table表插入當前操作的信息行。   
    create trigger iu_table   
    after insert or update on tr_table   
    for each row   
    begin  
        insert into ts_table select * from tr_table t where t.tab_id = :new.tab_id;   
    end is_table;   
  
    --對tr_table執行插入操作,觸發ts_table插入操作   
    insert into tr_table(tab_id,tab_name) values(1,'test');   
       
    --彈出錯誤信息提示   
    --ORA-04091:表tr_table發生了變化 觸發器/函數不能讀它   
    --ORA-06512: 在iu_table line 2   
    --ORA-04088: 觸發器iu_table 執行過程中出錯

 


 2、問題分析

:在Oracle中執行DML語句的時候是需要顯示進行提交操作的。當我們進行插入的時候,會觸發觸發器執行對觸發器作用表和擴展表的種種操作,但是這個時候觸發器和插入語句是在同一個事務管理中的,因此在插入語句沒有被提交的情況下,我們無法對觸發器作用表進行其他額外的操作。如果執行其他額外的操作則會拋出如上異常信息。

 


3、解決方案

:1,我們知道,出錯的原因是因為觸發器和DML語句在同一事務管理中,所以方案一便是將觸發器和DML語句分成兩個單獨的事務處理。這里可以使用Pragma autonomous_transaction; 告訴Oracle觸發器是自定義事務處理。

SQL語句如下:

 


      create trigger iu_table   
    after insert or update on tr_table   
    for each row   
    declare  --這里是關鍵的地方,在變量申明的地方,指定自定義事務處理。   
    pragma autonomous_transaction;    
    begin  
        insert into ts_table select * from tr_table t where t.tab_id = :new.tab_id;   
    --這里需要顯示提交事務   
        commit;   
    end iu_table;

 

   :2,在Oracle Trigger中有:new,:old兩個特殊變量,當觸發器為行級觸發器的時候,觸發器就會提供new和old兩個保存臨時行數據的特殊變量,我們可以從倆個特殊的變量中取出數據執行擴張表的DML操作。

SQL語句如下:

 

   

 create trigger iu_table   
    after insert on tr_table   
    for each row   
    begin  
        insert into ts_table(tab_id,tab_name) values(:new.tab_id,:new.tab_name);   
        --這里需要注意,要知道不同的觸發類型其特殊變量:new和:old保存的值的區別。   
        --commit; 注意使用方案二,這里不能顯示的進行提交操作操作,trigger中在沒有聲明自定義事務管理的時候,不能執行顯示提交。   
    end iu_table;

 

如果您覺得文章有用,也可以給水發個微信小額紅包鼓勵鼓勵!!!


免責聲明!

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



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