我在BEFORE INSERT TRIGGER上遇到一个奇怪的错误,我无法理解。即使在阅读了此处发布的类似问题的多个问题之后。
无法处理“方法”:category_id ='foo'和request_id ='99' 错误:java.sql.BatchUpdateException:ORA-04091:表SCHEMA.ANIMAL_TABLE 正在变异,触发/功能可能看不到它ORA-06512:at “SCHEMA.TRIGGER_NAME”,第7行ORA-04088:执行期间出错 触发'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 :(得分:0)
错误消息与更新表无关。您无法从 ROW级别触发器中当前正在更改的表中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语句中执行此操作:
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';
(请注意select and into列表中的两列)