【问题标题】:"Table is mutating" error occurs when inserting into a table that has an after insert trigger插入具有插入后触发器的表时发生“表正在变异”错误
【发布时间】:2016-06-17 17:41:44
【问题描述】:

我正在尝试创建一个插入后触发器,该触发器将购买的详细信息插入到购买日志表中,同时更新购买表中的总成本列以将 16.5% 的 GCT 添加到总成本中。这两个表有这些列:

    CREATE TABLE purchases 
    (
        p_Id        INTEGER     PRIMARY KEY,
        product     VARCHAR(25) ,
        quantity    INTEGER     ,
        unit_Cost   FLOAT       ,
        total_Cost  FLOAT       
    );

    CREATE TABLE purchases_log
    (
        event_Date      DATE        ,
        p_Id            INTEGER         PRIMARY KEY,
        description     varchar(75) 
    );

我尝试使用的触发器是:

CREATE OR REPLACE TRIGGER PURCHASES_AUDIT
AFTER INSERT ON purchases
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE TAX FLOAT;

BEGIN
INSERT INTO purchases_log
VALUES(SYSDATE,:NEW.p_Id,'INSERT INTO PURCHASES TABLE');
tax := 1.165;
UPDATE purchases SET total_Cost = quantity * unit_Cost;
UPDATE purchases SET total_Cost = total_Cost*tax;
END PURCHASES_AUDIT;
/

但是,当尝试在购买表上运行插入时,oracle 给了我这个错误

ERROR at line 1:
ORA-04091: table PURCHASES is mutating, trigger/function may
not see it
ORA-06512: at "PURCHASES_AUDIT", line 9
ORA-04088: error during execution of trigger 'PURCHASES_AUDIT'

请帮忙

【问题讨论】:

    标签: sql plsql oracle11g database-trigger


    【解决方案1】:

    不要update定义触发器的表。

    听起来您想要修改:new 伪记录的插入前触发器,而不是插入后触发器。如果我正确理解你的意图

    CREATE OR REPLACE TRIGGER PURCHASES_AUDIT
      BEFORE INSERT ON purchases
      FOR EACH ROW
    DECLARE 
      TAX FLOAT;
    BEGIN
      INSERT INTO purchases_log
        VALUES(SYSDATE,:NEW.p_Id,'INSERT INTO PURCHASES TABLE');
      tax := 1.165;
      :new.total_Cost = :new.quantity * :new.unit_Cost * tax;
    END PURCHASES_AUDIT;
    

    顺便说一句,您真的非常想使用float 而不是number?你完全理解浮点数的近似性质吗?我从来没有遇到过想使用float 的人。

    【讨论】:

    • 谢谢,请原谅我,但我有点新手。我实际上并不完全理解浮点数和数字之间的区别。不过,我将对这两种变量类型进行研究以备将来使用。
    • @tajay - 您可以了解每个开发人员都应该知道的关于浮点运算的知识docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html 但总而言之,float 是一种近似数据类型。 1 * 0.9 可能是 0.90000000000001。或者它可能是 0.89999999996。它会接近正确的值,但计算机无法准确表示浮点值,因此您会累积错误。如果您在进行科学计算时无论如何都会累积错误项,那这不是问题。不过,我从未见过有人乐于让货币价值不精确。
    • 哦,我现在明白了。谢谢
    【解决方案2】:

    澄清一点:之前触发器允许您更新 :new 值,之后触发器不允许。 :new 值 if after 触发器将始终包含最终值。

    【讨论】:

      猜你喜欢
      • 2013-07-17
      • 1970-01-01
      • 2015-02-05
      • 1970-01-01
      • 2019-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多