表正在变异,触发器/函数可能看不到它/ORA-04088: 执行触发器时出错

Posted

技术标签:

【中文标题】表正在变异,触发器/函数可能看不到它/ORA-04088: 执行触发器时出错【英文标题】:Table is mutating, trigger/function may not see it/ORA-04088: error during execution of trigger 【发布时间】:2018-10-02 03:52:40 【问题描述】:

以下是我的触发器,我很难实现。它会创建触发器,但在我更改价格后出现错误。以下触发器是当 DAYCARE 表的任何行发生价格变化(更新)时,向 DAYCARE_PRICE 表添加一行。

CREATE OR REPLACE TRIGGER daycare_price_history_trg
BEFORE UPDATE ON DAYCARE
FOR EACH ROW
BEGIN
    IF :NEW.price != :OLD.price THEN 
        INSERT INTO DAYCARE_PRICE(daycare_id, old_price, new_price, date_of_change)
        SELECT daycare_id, :NEW.price, :OLD.price, SYSDATE
        FROM DAYCARE;
    END IF;
END;

【问题讨论】:

简短回答:您不能从正在更新的 DAYCARE 中的同一行中进行选择。请改用 NEW/OLD。 请检查我的回答,如果对您有帮助,请接受。请阅读:***.com/help/someone-answers 了解为什么它很重要。 【参考方案1】:

使用VALUES 子句而不是从表(触发器所有者)中选择插入。

CREATE OR REPLACE TRIGGER daycare_price_history_trg BEFORE
     UPDATE ON daycare
     FOR EACH ROW
BEGIN
     IF
          :new.price !=:old.price
     THEN
          INSERT INTO daycare_price (
               daycare_id,
               old_price,
               new_price,
               date_of_change
          ) VALUES (
               :new.daycare_id,
               :old.price,
               :new.price,
               SYSDATE
          );
     END IF;
END;
/

【讨论】:

这不起作用...我收到以下错误:ORA-00984: column not allowed here Errors: check compiler log @MMC :您在复制和重写实际代码时犯了一些错误。鉴于您对DAYCARE_PRICE 的表定义,这应该可以工作。看来您没有在需要它的地方指定 :new 关键字(daycare_id )或什么?彻底检查。 我试着完全复制你的命令。另外,我确实想指出 daycare_id 不是新的。它应该保持与日托表中调用的相同。 你最好在“AFTER”触发器中做这些事情:“before”触发器中的:new和:old值可以被其他“before”触发器改变......如果有另一个“ before" 触发器执行类似 ":new.new_price := round(:new_price)" 之类的操作,而另一个触发器在您的触发器之后运行,您将记录错误的值。相反,在触发器之后,当数据已经写入并且是确定的时运行。 @MMC :这并不意味着您应该直接使用列名daycare_id,而INSERT 中没有:NEW:OLD 限定符,这就是错误的原因。如果您确实希望它保持不变,请尝试使用:OLD.daycare_id 而不是:NEW

以上是关于表正在变异,触发器/函数可能看不到它/ORA-04088: 执行触发器时出错的主要内容,如果未能解决你的问题,请参考以下文章

表正在变异,触发器/函数可能看不到它;需要后/行级查询

ORA-04091: 表 JOSEP.EMP 正在变异,触发器/函数可能看不到它

ORA-04091: 表 [blah] 正在变异,触发器/函数可能看不到它

表正在变异,触发器/函数可能看不到它/ORA-04088: 执行触发器时出错

Oracle - 在没有触发器的情况下更新表时出现“表正在变异,触发器/函数可能看不到它”错误

表正在变异,触发器/函数可能看不到它(阻止平均成绩降至 2.5 以下)