经常会有人提出这样的问题:“有一个这样的问题,有一个表A有 a,b,c,d四个字段,修改一条记录d的值为2的倍数,希望把该记录插入相同结构的表B中。并删除A表的这条记录。”
相关SQL:
--一张表
--基于这张表的触发器
这个函数在执行的时候会报告这样的错误:“ORA-04091:表SCOTT.FOO 发生了变化,触发器/函数不能读它”。网上有很多关于该错误的解决方案,其中,有很大一部分是增加PRAGMA AUTONOMOUS_TRANSACTION语句,设置该触发器为自治事务,然后避免该错误。增加之后确实不报错了,而且貌似可以执行了,但是事真的如此么?修改之后的触发器如下:
让我们通过真实的数据来验证这个解决方案的不可行:
ChenZw> insert into foo values(1,1,1,2);
已创建 1 行。
ChenZw> select * from foo;
A B C D
---------- ---------- ---------- ----------
1 1 1 2
已选择 1 行。
--看,(1,1,1,2) 这条数据居然是可以插入的!
ChenZw> insert into foo values(2,2,2,2);
已创建 1 行。
ChenZw> select * from foo;
A B C D
---------- ---------- ---------- ----------
1 1 1 2
2 2 2 2
已选择2行。
-- 吆吆,我又插入了一条(2,2,2,2),是不是触发器失效了呀?
ChenZw> commit;
提交完成。
ChenZw> insert into foo values(3,3,3,2);
已创建 1 行。
-- 再插入一条数据
ChenZw> commit;
提交完成。
ChenZw> select * from foo;
A B C D
---------- ---------- ---------- ----------
3 3 3 2
已选择 1 行。
--这里,为什么? 为什么把我之前的数据都给我删掉了,而不是刚刚插入的那条?
总结一下,这里插入的执行顺序应该是这样的:
1)INSERT开启一个新的事务,写入一条(3,3,3,2)数据,但是该操作尚未提交。
2)触发器语句块执行,开启一个自治事务,删除表中的数据,但是WHERE FOO.D = :NEW.D能够圈到的包含(1,1,1,2),(2,2,2,2)两条数据,由于(3,3,3,2)与触发器不在一个事务中,并且未提交,所以触发器语句块看不到当前的数据。
3)触发器删除语句执行完成,然后提交。
4)INSERT语句的事务完成,提交。
作者 陈字文(热衷于PM\ORACLE\JAVA等,欢迎同行交流):ziwen#163.com 扣扣:4零9零2零1零零
所以有两点建议:
1)对于INSERT一条语句到数据库中,不要希望能通过触发器来删除该语句。
2)尝试从业务端来解决这个需求。
相关推荐
登陆oracle时出现ora-15414时 按照文档操作即可 安全无压力
Oracle 11gr2连Oracle 19c 报ORA-28040 ORA-01017解决方法
ERwin连接oracle报ORA-01041内部错误,hostdef扩展名不存在解决办法,实验可解决问题。
Oracle_ORA-12518故障_处理,希望在此与大家分享,能够在实际的工作中提高解决问题的能力
使用工具IMPDP导入数据时ORA-39002、ORA-39070错误排查。使用工具IMPDP导入数据时ORA-39002、ORA-39070错误排查 使用工具IMPDP导入数据时ORA-39002、ORA-39070错误排查
kettle连接oracle12C--报错ORA-28040 没有匹配的验证协议
NULL 博文链接:https://ajita.iteye.com/blog/1725304
错误描述:oracle远程连接服务器出现 ORA-12170 TNS:连接超时 错误检查:有很多是oracle自身安装的问题,但是我这里服务器配置正常,监听正常,服务正常,远程可以ping通服务器。 这里主要是防火墙问题,解决办法: ...
ora-00604 错误 解决 方法 ora-00604 错误 解决 方法 ora-00604 错误 解决 方法 ora-00604 错误 解决 方法 ora-00604 错误 解决 方法ora-00604 错误 解决 方法
用oracle数据库新建连接时遇到ora-12505,此问题解决后又出现ora-12519错误,郁闷的半天,经过一番折腾问题解决,下面小编把我的两种解决方案分享给大家,仅供参考。 解决方案一: 今天工作时在新建连接的时候遇到...
oracle数据库ora-01152和ora-01110的解决办法
前几天升级Oracle数据库,从11.2.0.1升级至11.2.0.4,安装完成后,打开PL/SQL,显示ORA-12514,如图: 问题阐述 ORA-12514:监听程序当前无法识别链接描述符中请求的服务,简单的来说就是Oracle数据库的监听器配置有...
ORACLE ORA-00132 ORA-00214
ora-03113错误
客户端进行连接的时候,系统不定期出现ora-12520,ora-12516的连接问题, 问题解决方案建议: 1、增加process和session的连接数。 2、检查连接的应用,是不是有没有释放的连接。 3、将修改参数local_listener中的vip为...
oracle启动失败,ORA-00702报错,windows,linux系统下解决办法
当任何试图分配一个大的连续的共享池中的内存失败,Oracle首先会刷新掉共享池中所有目前不在使用的对象,然后使得内存块被合并在一起。如果内存块仍然不够满足需求,那么就会出现ORA- 04031错误。这些错误同样可能...
ORACLE遭遇ORA-12899错误.doc
oracle12c程序连接时异常: ORA-01017: 用户名/口令无效; 登录被拒绝 的解决方案。
关于WIN10系统使用oracle instant client 时候提示ORA-01019错误的解决方案,本方案是配置好环境变量后依然提示ORA-01019错误的解决方案,内附本人制作测试的全过程说明