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

 更新时间:2023年05月10日 16:38:10   作者:悄悄小土豆  
这篇文章主要介绍了关于ORA-04091异常的出现原因分析及解决方案,本文给大家分享异常出现的场景及解决代码,感兴趣的朋友跟随小编一起看看吧

1、异常出现的场景.

:在使用Hibernate做为项目持久层的情况下,需要对某一张表进行一个扩展,扩展操作便是在该表上创建一个触发器。将表中的数据读入到其他表中。

-4091,ORA-04091: 表 DD123.DO_TABLE_47 发生了变化, 触发器/函数不能读它

SQL语句如下:

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语句如下:

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;
 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;   

到此这篇关于关于ORA-04091异常的出现原因,以及解决方案的文章就介绍到这了,更多相关ORA-04091异常内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解析如何查看Oracle数据库中某张表的字段个数

    解析如何查看Oracle数据库中某张表的字段个数

    本篇文章是对查看Oracle数据库中某张表的字段个数进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • DBCA命令行搭建Oracle ADG的流程

    DBCA命令行搭建Oracle ADG的流程

    随着Oracle数据库版本的更迭,搭建备库的方式多种多样。今天介绍一种创建物理备库的新方式,从12C版本开始推出:使用 DBCA 命令行,需要的朋友参考下吧
    2021-06-06
  • oracle中 procedure(存储过程)和function(函数)本质区别

    oracle中 procedure(存储过程)和function(函数)本质区别

    这篇文章主要介绍了 oracle中 procedure(存储过程)和function(函数)本质区别,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-02-02
  • ORACLE创建dblink的详细步骤

    ORACLE创建dblink的详细步骤

    dblink数据库链接顾名思义就是数据库的链接,当我们要跨本地数据库,访问另外一个数据库表中的数据时,通过dblink本地数据库可以像访问本地数据库一样访问远程数据库表中的数据,这篇文章主要介绍了ORACLE如何创建dblink,需要的朋友可以参考下
    2024-06-06
  • linux自动运行rman增量备份脚本

    linux自动运行rman增量备份脚本

    这篇文章主要介绍了linux自动运行rman增量备份脚本,实现周日和周三凌晨1:00执行0级全库备份,周一、二、四、五、六凌晨1:30执行增量备份,需要的朋友可以参考下
    2014-03-03
  • 在Oracle的函数中,返回表类型的语句

    在Oracle的函数中,返回表类型的语句

    在SQL Server中有表变量,可以在function中方便地返回,习惯SQL Server或者需要把脚本从SQL Server转到Oracle中的朋友可以都会碰到这个问题
    2012-10-10
  • oracle group by语句实例测试

    oracle group by语句实例测试

    本文将详细介绍oracle group by语句,以实例进行测试,需要的朋友可以参考下
    2012-11-11
  • oracle中函数 trunc(),round(),ceil(),floor的使用详解

    oracle中函数 trunc(),round(),ceil(),floor的使用详解

    这篇文章主要介绍了oracle中函数 trunc(),round(),ceil(),floor的使用详解的相关资料,需要的朋友可以参考下
    2017-03-03
  • Oracle数据库查看锁表语句和解锁的方法示例

    Oracle数据库查看锁表语句和解锁的方法示例

    在DBA的日常工作中,经常遇到为Oracle用户解锁的操作,这篇文章主要给大家介绍了关于Oracle数据库查看锁表语句和解锁的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-10-10
  • ORACLE中段的HEADER_BLOCK示例详析

    ORACLE中段的HEADER_BLOCK示例详析

    这篇文章主要给大家介绍了关于ORACLE中段的HEADER_BLOCK的相关资料,文中通过是示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-09-09

最新评论