问题描述
- ORACLE 触发器中 使用游标查询 本表 报错ORA-04091
-
racle 触发器.
监听表A 更新 更新后触发.
其中 使用游标查询表A 数据.
OPEN 游标时
会报 ORA-04091:表A发生了变化,触发器/函数不能读它于是增加了自定义事物 pragma autonomous_transaction;
增加事物之后不报错了.但是OPEN 的游标 没有获取到任何数据.想做到的效果是
是这样. 比如说表A里面有4条数据
1 aaaa
2 bbbb
3 cccc
4 dddd完后在修改其中一条数据之后. 查询其余没有修改的3条数据.在插入到表B中.
所以这里我想查询触发器监听的表.
我应该怎么处理?有什么好的建议.我刚才尝试了一下勇士图 依然会同样报错
解决方案
或者参考一下这个
相信写过ORACLE行级触发器的IT同仁们大多遇到过ORA-04091问题,即在某表的行级触发器中不能读取当前表的问题,如:
create table test(id raw(16), name varchar2(100), primary key (id));
create table test_count(test_count int);
insert into test_count values(0);
commit;
create or replace trigger t_test
AFTER INSERT OR DELETE ON test
FOR EACH ROW
BEGIN
UPDATE test_count
SET test_count = (SELECT count(*) from test);
END t_test;
/
当您在插入test表时,系统会抱怨(当然计数这样的简单业务是不需要使用触发器来做的,仅用于举例):
第 1 行出现错误:
RA-04091: 表 TEST.TEST 发生了变化, 触发器/函数不能读它
RA-06512: 在 "TEST.T_TEST", line 2
RA-04088: 触发器 'TEST.T_TEST' 执行过程中出错
前几天看到触发器的INSTEAD OF子句,顺便用它搞定:
drop trigger t_test;
create view v_test as select id, name from test;
create or replace trigger t_v_test
INSTEAD OF INSERT OR DELETE OR UPDATE ON v_test
FOR EACH ROW
DECLARE
BEGIN
IF inserting THEN
INSERT INTO test(id, name) values(:new.id, :new.name);
END IF;
IF deleting THEN
DELETE FROM test WHERE id = :old.id;
END IF;
IF updating THEN
UPDATE test
SET id = :new.id, name = :new.name
WHERE id = :old.id;
ELSE
UPDATE test_count
SET test_count = (SELECT count(*) from test);
END IF;
END t_v_test;
/
原来对test表的插入改为对v_test插入,一切OK,搞定。
解决方案二:
行级触发器是不允许select自身的,需要表级触发器才可以引用自身,建议你换个方法来实现
解决方案三:
ORACLE的触发器规则中,不能读取已经发生变更但没有提交事务的数据,修改前的内容使用 old.field 获取,修改后的值使用 new.field 获取,其中 field 是你的字段名
解决方案四:
第 1 行出现错误:
RA-04091: 表 TEST.TEST 发生了变化, 触发器/函数不能读它, line 2
RA-04088: 触发器 'TEST.T_TEST' 执行过程中出错 就是这个意思,建议看下触发器、函数的使用,
解决方案五:
第 1 行出现错误:
RA-04091: 表 TEST.TEST 发生了变化, 触发器/函数不能读它, line 2
RA-04088: 触发器 'TEST.T_TEST' 执行过程中出错 就是这个意思,建议看下触发器、函数的使用,
解决方案六:
Oracle 触发器中使用游标