【问题标题】:Table is mutating, trigger/function may not see it/ORA-04088: error during execution of trigger表正在变异,触发器/函数可能看不到它/ORA-04088: 执行触发器时出错
【发布时间】: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。
  • 请检查我的回答,如果对您有帮助,请接受。请阅读:stackoverflow.com/help/someone-answers 了解为什么它很重要。

标签: oracle plsql


【解决方案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
猜你喜欢
  • 2021-12-20
  • 2022-10-20
  • 2011-03-01
  • 2015-06-28
  • 1970-01-01
  • 2019-03-12
  • 2010-09-27
  • 2013-11-24
  • 2016-08-11
相关资源
最近更新 更多