我正在插入表格:
fruit:
fruit_id | name
-----------|----------
1 | apple
----------------------
我有另一张桌子:
basket:
basket_id | fruit_id | name
------------|--------------|-----------
345 | 1 | apple
789 | 2 | grape
当我插入时:
insert into fruit (fruit_id) values (2)
我想更新"名称"列基于购物篮表中的名称。
我正在尝试使用此触发器执行此操作:
create trigger add_fruit_name
after insert
on fruit
for each row
DECLARE
BEGIN
update fruit
set (name) =
(select name from basket
where :new.fruit_id = basket.fruit_id);
commit;
END;
/
我尝试使用此触发器插入时的错误是:
table FRUIT is mutating, trigger/function may not see it
任何想法?
答案 0 :(得分:1)
Mutating触发器意味着数据在触发器触发时发生变化,在你的情况下,你正在更新(DML操作)同一个表,在插入(DML操作)上同一个,这意味着触发器不会看到可能因此错误+它有一个提交,而不是在AUTONOMOUS_TRANSATION(在PRAGMA上阅读更多内容以了解它)。 现在,作为一般规则,触发器不应该提交,除非它们处于自治事务中,这是通过声明上述PRAGMA(仅在极端情况下)来完成的。 我会这样写触发器:
create trigger add_fruit_name
before insert
on fruit
for each row
DECLARE
BEGIN
select b.name
into :new.name
from basket b
where b.fruit_id = :new.fruit_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
raise_application_error (-20001,'No fruit found in table basket for fruit_id: ' || to_char(:new.fruit_id));
WHEN OTHERS THEN
raise_application_error (-20002, 'Trigger add_fruit_name raised an error' || SQLERRM);
END;
/
另一种方法是编辑将行插入水果表并使其适当更新的函数/过程。
要理解的一篇小而重要的文章 - check this out!
干杯