PRAGMA AUTONOMOUS_TRANSACTION
我使用以下语句重现了您的错误:
create table item_master(item number, item_parent number);
insert into item_master values (1, 10);
insert into item_master values (2, 10);
create table tmp_chk(item number, item_parent number);
create table staging_tbl(create_date date, table_name varchar2(30), item_sku number, if_name varchar2(10));
我使用了您的触发器(在END IF
从触发器末尾删除残留代码之后)。我得到了错误"ORA-04091: table name is mutating, trigger/function may not see it." message.
参考这个很好的解释Fix Oracle mutating trigger table errors,必须重申以下摘录:
归根结底,变异表错误通常是由于应用程序设计不佳造成的,应尽可能避免变异触发器。
在参考中的第四个选项之后autonomous transactions
,我重写了您的触发器,如下所示:
create or replace TRIGGER a_del_trg
after delete on item_master
for each row
DECLARE
l_item NUMBER :=0;
l_item_parent number :=0;
pragma autonomous_transaction;
BEGIN
INSERT INTO tmp_chk (item,item_parent) VALUES (:OLD.item,:OLD.item_parent);
SELECT a.item,a.item_parent INTO l_item , l_item_parent
FROM item_master a , tmp_chk b WHERE a.item_parent = b.item_parent
and a.item != b.item;
INSERT INTO staging_tbl
(create_date, table_name, item_sku, if_name)
values
(SYSDATE, 'Item_master', l_item, 'W'); -- want to add the remaining item here
commit;
END a_del_trg;
/
运行查询:
select * from item_master;
2 10
select * from tmp_chk ;
1 10
select * from staging_tbl;
27-NOV-15 Item_master 2 W
回滚
从这里:
“......在 1000 次中的 999 次中,如果您发现自己“被迫”使用自主事务 - 这可能意味着您有一个您没有考虑过的严重数据完整性问题。
人们在哪里尝试使用它们?
- 在那个调用提交的过程(不是错误记录例程)的触发器中。哎呀,回滚的时候一定很痛。
- 在那个获取变异表约束的触发器中。哎哟,更痛了
- 错误记录 - 好的。
- 几乎所有其他东西 - 都不好。”