2011-09-16 43 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

很好的答案...我添加了一个补充。 –