2015-09-23 28 views
0

我試圖按照指示在Mutating Table Compound Trigger更新基於一個子表的id父表和避免變異表錯誤。試圖解決變異表的問題與複合觸發器

我需要獲得在BLATChildren表中當前記錄的父ID(BLATranscriptId),然後子記錄完成的更新,我需要提取符合我的條件的當前計數和執行更新在父表BLATranscript上。

這個錯誤已經解決了 - 我得到一個錯誤,我的綁定變量「transcriptID」在我的代碼的「AFTER EACH ROW」部分中不好。我已驗證BLATChildren.BLATranscriptId是否存在,拼寫是否正確。 解決方案是改變每行後發言之後。

NEW ISSUE - 觸發器更新父表中的每條記錄,而不僅僅是匹配的父記錄。

任何幫助將不勝感激。謝謝。

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; 
/
+1

不能引用在其上觸發器在觸發任何行級部分定義的表。您需要在觸發器的聲明級別部分執行此操作。幾乎可以確定你想要你的局部變量是一個集合,而不是一個標量,並希望您的觸發器的語句級部分遍歷集合中的元素。您在觸發器語句級部分中對局部變量的引用不會以冒號開頭。只需使用'transcriptID'而不是':transcriptID'(或任何你命名你的集合)。 –

+0

@sstan - 謝謝。這解決了BIND變量問題,但現在它給我一個關於我試圖避免的變異表問題的問題。 – Trebor

+0

@JustinCave - 謝謝。我通過集合假設你正在考慮更接近文檔使用臨時表的東西嗎?我有一個心理障礙,因爲對我來說,每次更新子記錄時,它都會更新父表中的每條記錄。我顯然不是很瞭解這一點。 – Trebor

回答

0

你需要爲每排部收集:new.blaTranscriptid INT PL/SQL表
後聲明中的一部分將使用這個PL/SQL表進行更新。
喜歡:

CREATE OR REPLACE TRIGGER transcript_after_update 
FOR UPDATE of enrollmentStatus,completionDate on blatChildren 
COMPOUND TRIGGER 
    TYPE transcriptIDs_t IS TABLE OF blatChildren.blaTranscriptid%TYPE; 
    transcriptID transcriptIDs_t := transcriptIDs_t(); 
BEFORE EACH ROW IS 
BEGIN 
    transcriptID.extend; 
     transcriptID(transcriptID.count) := :new.blaTranscriptid; 
END BEFORE EACH ROW;  
AFTER STATEMENT IS 
BEGIN 
    FOR i IN 1..transcriptID.COUNT 
    LOOP 
    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(i) 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(i) 
    and blac.enrollmentStatus='C')); 
    END LOOP; 
END AFTER STATEMENT; 
END; 
/
+0

你是說使用PL/SQL表而不是綁定變量嗎? – Trebor

+0

我張貼觸發例子(但我沒有甲骨文附近,所以有些錯別字可能存在)。類型數量的變量不是你需要的,因爲它只能存儲1個值,所以如果外部UPDATE語句將更新多行,那麼在觸發器UPDATE語句中將只使用一個最新值。 –

+0

感謝這個例子。你已經在你的EACH ROW部分做了一些我不熟悉的東西,所以我需要一點研究來理解這一切。非常感謝。在我做了更多研究並嘗試完成後,我會回來。 – Trebor