2011-09-16 73 views
0

我在BEFORE INSERT TRIGGER上看到一個奇怪的錯誤,我不明白。即使閱讀了這裏發佈的類似問題的多個問題。java.sql.BatchUpdateException:在插入觸發器之前的ORA-04091

failed to process "method": category_id = 'foo' and request_id = '99' error: java.sql.BatchUpdateException: ORA-04091: table SCHEMA.ANIMAL_TABLE is mutating, trigger/function may not see it ORA-06512: at "SCHEMA.TRIGGER_NAME", line 7 ORA-04088: error during execution of trigger 'SCHEMA.TRIGGER_NAME'

這裏是觸發:

CREATE OR REPLACE TRIGGER TRIGGER_NAME 
BEFORE INSERT ON animal_table FOR EACH ROW WHEN (NEW.animal_type = 'cats') 

DECLARE base_animal_id NUMBER(19,0); base_amount NUMBER(19,0); 

BEGIN 

SELECT animal_nbr INTO base_animal_id 
FROM animal_table 
WHERE category_id = :NEW.category_id AND summary_id = :NEW.summary_id 
AND animal_type = 'special'; 

SELECT animal_amount INTO base_amount 
FROM animal_table 
WHERE category_id = :NEW.category_id AND summary_id = :NEW.summary_id 
AND animal_type = 'special'; 


IF :NEW.category_id = 'foo' THEN 

    :NEW.animal_info1 := base_animal_id; 
    :NEW.animal_info2 := base_amount; 
    :NEW.animal_info3 := '00'; 

END IF; 

END; 

我知道關於它的觸發被關押在同一個表的修改規則,但我也是紅色的東西,就應該更換新的列時工作,僅適用於:NEW字段。我也認爲它可能缺少UPDATE作爲觸發事件,但情況並非如此。任何人都可以幫助我嗎?因爲我是觸發器和PL/SQL的新手。

+0

謝謝,L ukas ...我正準備這樣做。 –

回答

0

該錯誤消息與更新表無關。您不能從行中當前正在更改的表中觸發SELECT

唯一的解決方法是將新行寫入行級觸發器中的中間表中。然後創建一個語句級別觸發器,用於處理已寫入中間表的所有行(很可能只有帶有子查詢的單個UPDATE語句)。

如果您可以確定要在語句級別觸發器內進行後處理的行,則您可能不用行級別觸發器和中間表。通過檢查animal_type ='cats'和category_id ='foo'。

如果是這樣的話,下面的觸發器(未經測試!)可能會做你想要的(而不是一個你有)

CREATE OR REPLACE TRIGGER TRIGGER_NAME 
AFTER INSERT ON animal_table 
BEGIN 

    UPDATE animal_table 
    SET (animal_info1, 
      animal_info2, 
      animal_info3) = (SELECT animal_nbr, animal_amount, '00' 
          FROM animal_table t2 
          WHERE t2.category_id = animal_table.category_id 
          AND t2.sumary_id = animal_table.summary_id 
          AND t2.animal_type = 'special' 
         ) 
    WHERE animal_type = 'cats' 
    AND category_id = 'foo' 

END; 

另一種更普遍的PL/SQL的事情:你不要」噸需要運行一個選擇要檢索每個列,你可以做,在一個單一的SELECT語句如果條件是相同的:

SELECT animal_nbr, animal_amount 
    INTO base_animal_id, base_amount 
FROM animal_table 
WHERE category_id = :NEW.category_id 
    AND summary_id = :NEW.summary_id 
    AND animal_type = 'special'; 

(請注意,在選擇進入列表中的兩列)

+0

很好的答案...我添加了一個補充。 –