根据Burleson,我们可以通过使用AFTER UPDATE避免变异表/触发器错误:
如果必须使用触发器,最好通过使用""来避免变异表错误。触发,以避免与变异表相关的货币问题。例如,使用触发器":在xxx"上更新后,原始更新已完成,表格不会发生变异。
然而,SO的这张海报正在使用AFTER UPDATE并仍然收到变异表错误。
我花了很多时间阅读各种帖子,并看到了各种解决方案和意见。我之前在自己的代码中使用AFTER UPDATE触发器几次看到这个错误 - 所以我怎么误解了Burleson所指的语法?
CREATE OR REPLACE TRIGGER transcript_after_update
AFTER UPDATE on blatChildren
FOR EACH ROW
BEGIN
update BLATranscript SET (enrollmentStatus, completionDate) = (select 'C',sysdate from dual)
where id in (select blat.id from BLATranscript blat
inner join BlendedActivity bla on blat.blendedactivityid=bla.id
where blat.id=:new.blaTranscriptId and minCompletion<=(
select count(countForCompletion) as total from blatChildren blac
inner join BlendedActivityMembership bam on blac.childActivityId=bam.childActivityId
where completionDate>=sysdate-acceptPrevWork
and blat.id=:new.blaTranscriptId));
END;
我已经在这里阅读了关于SO的各种帖子和意见,并询问有关糟糕的编程,规范化,使它们自主(或者为什么你不应该)以及为什么你不应该使用触发器等我对我如何错误地解释Burleson或者他的陈述是否错误更感兴趣。在我看来,更新完成后数据的状态应该是稳定的。
答案 0 :(得分:1)
语句级触发器(不是每行)将允许您查询基表而不会发生表错误
但在这种情况下,您将无法使用:old.
和:new.
变量,因此对您没有多大帮助。
可能的出路是使用2个触发器:
- 用于将ID-s存储到临时表的行级触发器,
- 语句级别触发器,用于根据此临时表运行更新。