ORA-04091 关于在oracle行级触发器中访问本表的错误解决

今天写了个触发器,创建的是行级触发器,
对于oracle行级触发器(for each row),不能对本表做任何操作,包括读取
原则:
在before insert触发器中,可以实现对本表的访问;
在after insert触发器中,不能实现对本表的访问;
在before/after update/delete触发器中,都不能实现对本表的访问

如果插入或修改一条数据时,需要更新另一张表的数据,但是由于在触发器中需要访问触发器本表,一直报ORA-04091错误,如果不使用行级触发器,那么则不能根据 :old.field1 , :NEW.field1访问新旧数据,在网络搜索百般后终于找到实用的解决方法,通过自治事务实现(修改触发器)。
现在将大致的测试场景重现。

原因:在行级触发器中,不能查询自身表
场景重现:通过触发器实现test_count表中统计test表中行数
--创建子表
create table TEST
(id NUMBER, name varchar2(100), primary key (id));
--创建统计表
create table test_count (test_count int);
--创建触发器
CREATE OR REPLACE TRIGGER T_TEST
AFTER INSERT OR DELETE ON TEST
FOR EACH ROW
DECLARE
A NUMBER;
BEGIN
SELECT COUNT(*) INTO A FROM TEST;
UPDATE TEST_COUNT SET TEST_COUNT = A;
END T_TEST;

模拟错误:
INSERT INTO TEST (ID,NAME)VALUES(2,'abc');
ORA-04091: table CHF.TEST is mutating, trigger/function may not see it
ORA-06512: at "CHF.T_TEST", line 2
ORA-04088: error during execution of trigger 'CHF.T_TEST'

处理方法:
通过自治事务实现(修改触发器)
CREATE OR REPLACE TRIGGER T_TEST
AFTER INSERT OR DELETE ON TEST
FOR EACH ROW
DECLARE
A NUMBER;
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
SELECT COUNT(*) INTO A FROM TEST;
UPDATE TEST_COUNT SET TEST_COUNT = A;
COMMIT;
END T_TEST;

PRAGMA AUTONOMOUS_TRANSACTION
当前的触发器作为已有事务的子事务运行,子事务自治管理,子事务的commit、rollback操作不影响父事务的状态

解决方法来自 http://www.xifenfei.com/1214.html/comment-page-1 懒得编辑后面照搬过来了,纯属资料学习,别无它用,谢谢。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值