AFTER UPDATE触发器上的变异表错误

时间:2015-09-23 14:52:02

标签: oracle

根据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或者他的陈述是否错误更感兴趣。在我看来,更新完成后数据的状态应该是稳定的。

1 个答案:

答案 0 :(得分:1)

语句级触发器(不是每行)将允许您查询基表而不会发生表错误 但在这种情况下,您将无法使用:old.:new.变量,因此对您没有多大帮助。
可能的出路是使用2个触发器:
  - 用于将ID-s存储到临时表的行级触发器,
  - 语句级别触发器,用于根据此临时表运行更新。