【发布时间】:2015-09-23 19:28:27
【问题描述】:
我正在尝试按照Mutating Table Compound Trigger 的说明根据子表的 id 更新父表并避免发生变异表错误。
我需要获取BLATChildren表中当前记录的父ID(BLATranscriptId),然后子记录更新完成后,我需要提取符合我条件的当前计数并对父表 BLATranscript 执行更新。
此错误已解决 - 我的绑定变量“transcriptID”在代码的“AFTER EACH ROW”部分中出现错误。我已经验证了 BLATChildren.BLATranscriptId 存在并且拼写正确。 解决方案 将 AFTER EACH ROW 更改为 AFTER STATEMENT。
新问题 - 触发器正在更新父表中的每条记录,而不仅仅是匹配的父记录。
任何帮助将不胜感激。谢谢。
CREATE OR REPLACE TRIGGER transcript_after_update
FOR UPDATE of enrollmentStatus,completionDate on blatChildren
COMPOUND TRIGGER
transcriptID number:=0;
BEFORE EACH ROW IS
BEGIN
transcriptID := :new.blaTranscriptid;
END BEFORE EACH ROW;
AFTER STATEMENT IS
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=transcriptID 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=transcriptID
and blac.enrollmentStatus='C'));
END AFTER STATEMENT;
END;
/
【问题讨论】:
-
您不能在触发器的任何行级部分引用定义触发器的表。您需要在触发器的语句级部分中执行此操作。您几乎肯定希望您的局部变量是一个集合,而不是一个标量,并且您希望触发器的语句级部分迭代集合的元素。您在触发器的语句级部分中对局部变量的引用不会以冒号开头。只需使用
transcriptID而不是:transcriptID(或任何您为收藏命名的名称)。 -
@sstan - 谢谢。这解决了 BIND 变量问题,但是现在它给了我一个关于我试图避免的变异表问题的问题。
-
@JustinCave - 谢谢。我假设通过收集您正在考虑更接近于文档使用的临时表?不过,我有一个心理障碍,因为在我看来,每次更新子记录时它都会更新父表中的每条记录。我显然不是很了解这一点。
-
文档使用的是集合(特别是嵌套表)而不是临时表。但是,是的,这就是我建议你遵循的。最有可能的是,您希望触发器的行级部分将
:new.transactionID添加到集合中,然后您希望在您的触发器来确定要更新的行。 -
@JustinCave - 谢谢。我会尝试一下,并在我尝试完全按照示例进行操作后返回并提供更新。
标签: oracle