關(guān)于ORA-04091異常的出現(xiàn)原因分析及解決方案
1、異常出現(xiàn)的場(chǎng)景.
:在使用Hibernate做為項(xiàng)目持久層的情況下,需要對(duì)某一張表進(jìn)行一個(gè)擴(kuò)展,擴(kuò)展操作便是在該表上創(chuàng)建一個(gè)觸發(fā)器。將表中的數(shù)據(jù)讀入到其他表中。
-4091,ORA-04091: 表 DD123.DO_TABLE_47 發(fā)生了變化, 觸發(fā)器/函數(shù)不能讀它
SQL語(yǔ)句如下:
Sql代碼
drop table tr_table; create table tr_table( --觸發(fā)器作用表 tab_id number primary key, tab_name varchar2(30) NOT NULL ) create table ts_table as select * from tr_table; --提供擴(kuò)展功能的表 --定義的觸發(fā)器,在tr_table表插入和更新數(shù)據(jù)之后向ts_table表插入當(dāng)前操作的信息行。 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; --對(duì)tr_table執(zhí)行插入操作,觸發(fā)ts_table插入操作 insert into tr_table(tab_id,tab_name) values(1,'test'); --彈出錯(cuò)誤信息提示 --ORA-04091:表tr_table發(fā)生了變化 觸發(fā)器/函數(shù)不能讀它 --ORA-06512: 在iu_table line 2 --ORA-04088: 觸發(fā)器iu_table 執(zhí)行過(guò)程中出錯(cuò)
2、問(wèn)題分析
:在Oracle中執(zhí)行DML語(yǔ)句的時(shí)候是需要顯示進(jìn)行提交操作的。當(dāng)我們進(jìn)行插入的時(shí)候,會(huì)觸發(fā)觸發(fā)器執(zhí)行對(duì)觸發(fā)器作用表和擴(kuò)展表的種種操作,但是這個(gè)時(shí)候觸發(fā)器和插入語(yǔ)句是在同一個(gè)事務(wù)管理中的,因此在插入語(yǔ)句沒(méi)有被提交的情況下,我們無(wú)法對(duì)觸發(fā)器作用表進(jìn)行其他額外的操作。如果執(zhí)行其他額外的操作則會(huì)拋出如上異常信息。
3、解決方案
:1,我們知道,出錯(cuò)的原因是因?yàn)橛|發(fā)器和DML語(yǔ)句在同一事務(wù)管理中,所以方案一便是將觸發(fā)器和DML語(yǔ)句分成兩個(gè)單獨(dú)的事務(wù)處理。這里可以使用Pragma autonomous_transaction; 告訴Oracle觸發(fā)器是自定義事務(wù)處理。
SQL語(yǔ)句如下:
Sql代碼
create trigger iu_table after insert or update on tr_table for each row declare --這里是關(guān)鍵的地方,在變量申明的地方,指定自定義事務(wù)處理。 pragma autonomous_transaction; begin insert into ts_table select * from tr_table t where t.tab_id = :new.tab_id; --這里需要顯示提交事務(wù) commit; end iu_table;
create trigger iu_table after insert or update on tr_table for each row declare --這里是關(guān)鍵的地方,在變量申明的地方,指定自定義事務(wù)處理。 pragma autonomous_transaction; begin insert into ts_table select * from tr_table t where t.tab_id = :new.tab_id; --這里需要顯示提交事務(wù) commit; end iu_table;
:2,在Oracle Trigger中有:new,:old兩個(gè)特殊變量,當(dāng)觸發(fā)器為行級(jí)觸發(fā)器的時(shí)候,觸發(fā)器就會(huì)提供new和old兩個(gè)保存臨時(shí)行數(shù)據(jù)的特殊變量,我們可以從倆個(gè)特殊的變量中取出數(shù)據(jù)執(zhí)行擴(kuò)張表的DML操作。
SQL語(yǔ)句如下:
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); --這里需要注意,要知道不同的觸發(fā)類型其特殊變量:new和:old保存的值的區(qū)別。 --commit; 注意使用方案二,這里不能顯示的進(jìn)行提交操作操作,trigger中在沒(méi)有聲明自定義事務(wù)管理的時(shí)候,不能執(zhí)行顯示提交。 end iu_table;
到此這篇關(guān)于關(guān)于ORA-04091異常的出現(xiàn)原因,以及解決方案的文章就介紹到這了,更多相關(guān)ORA-04091異常內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
oracle?delete誤刪除表數(shù)據(jù)后如何恢復(fù)
最近在使用oracle數(shù)據(jù)時(shí),一不小心把table中的數(shù)據(jù)delete掉并且已經(jīng)提交了,下面這篇文章主要給大家介紹了關(guān)于oracle?delete誤刪除表數(shù)據(jù)后如何恢復(fù)的相關(guān)資料,需要的朋友可以參考下2022-06-06Oracle中的Connect/session和process的區(qū)別及關(guān)系介紹
本文將詳細(xì)探討下Oracle中的Connect/session和process的區(qū)別及關(guān)系,感興趣的你可以參考下,希望可以幫助到你2013-03-03Oracle觸發(fā)器表發(fā)生了變化 觸發(fā)器不能讀它的解決方法(必看)
下面小編就為大家?guī)?lái)一篇Oracle觸發(fā)器表發(fā)生了變化 觸發(fā)器不能讀它的解決方法(必看)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04oracle中如何查詢所有用戶表的表名、主鍵名稱、索引及外鍵等
在與Oracle進(jìn)行數(shù)據(jù)庫(kù)操作時(shí),往往會(huì)需要查詢數(shù)據(jù)庫(kù)表列表,以便對(duì)其進(jìn)行操作,這篇文章主要給大家介紹了關(guān)于oracle中如何查詢所有用戶表的表名、主鍵名稱、索引及外鍵等的相關(guān)資料,需要的朋友可以參考下2023-12-12Oracle與SQL Server在企業(yè)應(yīng)用的比較
Oracle與SQL Server在企業(yè)應(yīng)用的比較...2007-03-03oracle 視圖權(quán)限 oracle 創(chuàng)建視圖權(quán)限不足
在scott用戶下創(chuàng)建視圖的時(shí)候,報(bào)錯(cuò):權(quán)限不足,遇到這個(gè)問(wèn)題,我也是束手無(wú)策,于是網(wǎng)上搜集整理了一下,曬出來(lái)和大家分享,希望可以幫助你們2012-11-11