我以为我会写一个Oracle“表级”TRIGGER来避免为每个插入行调用MERGE。 编译器不会报告任何语法错误,但会发出以下错误报告:
ORA-04082:表级触发器中不允许使用新引用或旧引用
*操作:删除所有新旧引用
但事情就是这样:旧和新伪行有零引用! (有人可能会猜测发生了内部源到源重写,错误是关于隐藏代码的。)
问题:
我可以问“如何修复此代码以安抚编译器?”但我非常喜欢来了解幕后发生的事情,所以我将来可以避免这种情况。 (我假设没有办法查看重写。)
这是触发器代码
create or replace trigger remember_old_prop_part2
after insert on old_props_queue
begin
merge into event_extra dest
using (select event_key, property_name, string_value
from old_props_queue) src
on ( dest.event_key = src.event_key
AND dest.property_name = src.property_name)
when matched then
update set string_value = :src.string_value
when not matched then
insert (event_key, property_name, string_value)
values (:src.event_key, :src.property_name, :src.string_value);
-- once merged, nuke the queue
truncate table old_props_queue reuse storage;
end;
以下是
上触发的表格create table old_props_queue
( "EVENT_KEY" VARCHAR2(20 BYTE) NOT NULL ENABLE,
"PROPERTY_NAME" VARCHAR2(20 BYTE) NOT NULL ENABLE,
"STRING_VALUE" VARCHAR2(80 BYTE),
CONSTRAINT "PX_OLD_PROPS_QUEUE" PRIMARY KEY ("EVENT_KEY", "PROPERTY_NAME") DEFERRABLE );
答案 0 :(得分:2)
"对旧的和新的伪行没有引用! "
该错误具有误导性。当您引用子查询时,它反对的是那些冒号::src
应该只是src
。
一旦你修好了,你将不得不看看那个TRUNCATE。我们不能在触发器中包含DDL语句,因为DDL会发出隐式提交,并且我们无法在触发器中提交。最简单的解决方案是使用DELETE。