2016-09-19 59 views
0

我寫了一個複合觸發器來觸發插入。多個插入物一起被批處理併發送到複合觸發器拾取它的DB。我的問題是,我需要根據查詢提供的數據對某些插入的同一張表執行更新查詢。我無法運行行級別操作,因爲這會導致觸發表錯誤(ORA-4091)。我能想到的最好的事情是在語句塊之前或之後有更新查詢。我不能在前面的語句塊中使用它,因爲每次更新都依賴於單個插入,並且在實際到達該查詢之前無法知道值。所以我創建了一個「類型」表,並在每行被修改之前更新它,然後在後面的語句塊中遍歷類型表並使用表上的數據執行更新查詢。無論我嘗試過什麼,After語句塊只會執行最後一次插入的更新查詢。批處理插入PL SQL複合觸發器

TYPE apple IS RECORD (v_size apple_t.size%Type, v_color apple_t.color%Type); 
    TYPE t_apple IS TABLE OF apple INDEX BY VARCHAR2(20); 

BEFORE ROW 
    t_apple(key).v_size := :New.size; 
    t_apple(key).v_color := :New.color; 
END BEFORE ROW 

AFTER STATEMENT 
    Iterator := t_apple.First; 
    LOOP EXIT WHEN ITERATOR IS NULL; 
     UPDATE apple_t SET SIZE = 10 
     WHERE color = t_apple(Iterator).color; 
     Iterator := t_apple.Next(Iterator); 
    END LOOP 
END AFTER STATEMENT 

這基本上是如何設計觸發器。使用第二張表是不可能的,因爲觸發成本是一個主要因素。任何指針?請和Thankyou

+1

你在BEFOR部分使用什麼值作爲「鑰匙」?它是不同的/唯一的你正在插入的排行? – schurik

+0

觸發器是否存在或您嘗試創建。如果存在,發佈完整的觸發器主體 – XING

+0

@schurik這是來自應用程序端的VARCHAR值。它對於任何給定的插入批次都是唯一的,但對於整個表格來說並不是唯一的。 – tharindus609

回答

1

我不完全理解,但我認爲你可以在每行之後得到你的密鑰,然後更新statament塊中的數據如下。

declare 
idx number := 1 ; 
type array_t is varray(10000) of varchar2(100) ; 
colorArr array_t := array_t(); 

    AFTER EACH ROW IS 
    BEGIN 
     if inserting then 
      colorArr (idx) := :new.color; 
      idx := idx + 1 ; 
     end if; 
    END 
    AFTER EACH ROW; 

    AFTER STATEMENT IS 
    BEGIN 
     for i in 1..sicilNoCol.count 
     loop 
      -- update here 
     end loop; 
    END AFTER STATEMENT; 

或者你爲什麼不寫一個簡單的插入觸發器,你可以manuplate:new.size在裏面?它給表可變的錯誤?

+0

原來我使用的觸發邏輯是正確的,我只是簡單地添加了一個額外的驗證來停止向表中添加不必要的記錄。標記你的正確答案 – tharindus609

+0

我也想指出,使用數組是不可能的,因爲表格每分鐘處理數以百萬計的查詢並使用一個大小的數組將會非常昂貴,我還需要保持數據插入延遲最小值這個邏輯不會給出表格變異錯誤,因爲在數據插入完成後執行實際的更新查詢。 – tharindus609