使用视图行级触发器解决ORA-04091不能读当前表
相信写过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,搞定。