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;
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;
如果您覺得文章有用,也可以給水發個微信小額紅包鼓勵鼓勵!!!
總結
以上是生活随笔為你收集整理的2013年1月18日调试触发器“表发生了变化,触发器或函数不能读它”的出现原因,以及解决方案...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022湖南石油化工职业技术学院专业排名
- 下一篇: SQLServer如何删除字段中的某个字