Heim  >  Artikel  >  Datenbank  >  关于ORA-04091异常的出现原因,以及解决方案

关于ORA-04091异常的出现原因,以及解决方案

WBOY
WBOYOriginal
2016-06-07 17:30:40985Durchsuche

在Oracle中执行DML语句的时候是需要显示进行提交操作的。当我们进行插入的时候,会触发触发器执行对触发器作用表和扩展表的种种操

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;

相关阅读:

Oracle触发器给表自身的字段重新赋值出现ORA-04091异常

linux

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn