使用触发器更新插入的行

时间:2017-07-25 21:13:01

标签: oracle plsql database-trigger

我正在插入表格:

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

任何想法?

1 个答案:

答案 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

干杯