【问题标题】:ORA-04091: table is mutating, trigger/function may not see it error during execution of oracle triggerORA-04091: table is mutating, trigger/function may not see it error during execution of oracle trigger
【发布时间】:2015-12-19 09:27:22
【问题描述】:

我有下面的触发器,对于FIELD_NAME 字段,我想将值插入到FIELD_TRACKING 表中作为'Deactivation time of KPI in case of Downtime(Select KPI_FREQ_TIME_UNIT FROM KPI_DEFINITION)'。此字符串值中的括号部分来自KPI_DEFINITION 表的KPI_FREQ_TIME_UNIT 字段。所以下面是我为此写的触发器。触发器编译没有任何错误。但是当我尝试从KPI_DEFINITION 表中更改DNTM_REAC_AFTER_HRS 字段时,我收到错误ORA-04091: table RATOR_MONITORING_CONFIGURATION.KPI_DEFINITION is mutating, trigger/function may not see it ORA-04088: error during execution of trigger 'RATOR_MONITORING_CONFIGURATION.TRG_TRK_KPI_DEFINITION'

create or replace TRIGGER RATOR_MONITORING_CONFIGURATION."TRG_TRK_KPI_DEFINITION" AFTER UPDATE ON RATOR_MONITORING_CONFIGURATION.KPI_DEFINITION
      FOR EACH ROW

    IF NOT  :old.DNTM_REAC_AFTER_HRS=:new.DNTM_REAC_AFTER_HRS THEN
        INSERT INTO RATOR_MONITORING_CONFIGURATION.FIELD_TRACKING  (FIELD_TRACKING_ID,TABLE_NAME,TABLE_ID, FIELD_NAME,FIELD_OLD_VALUE,FIELD_NEW_VALUE,USER_ID, TIMESTAMP, FIELD_TRACKING_COMMENTS)
        VALUES (FIELD_TRACKING_SEQ.NEXTVAL,'KPI_DEFINITION',:new.KPI_DEF_ID,'Deactivation time of KPI in case of Downtime'|| '(' || to_char((Select KPI_FREQ_TIME_UNIT FROM KPI_DEFINITION)) || ')',to_char(:old.DNTM_REAC_AFTER_HRS),to_char( :new.DNTM_REAC_AFTER_HRS),:new.LAST_UPDATED_BY,:new.LAST_UPDATED_DATE, decode(:new.KPI_ACTIVE_DOWNTIME,'N','This KPI has been reactivated on end of a downtime.',''));
      END IF;

    END;

【问题讨论】:

    标签: oracle triggers sql-insert


    【解决方案1】:

    触发器无法读取表(从 KPI_DEFINITION 中选择 KPI_FREQ_TIME_UNIT),这会发生变化...您可以通过以下方式访问该值::new.KPI_FREQ_TIME_UNIT。 更多信息:http://www.dba-oracle.com/t_avoiding_mutating_table_error.htm

    其他情况你可以尝试在autonomous transaction

    create or replace TRIGGER RATOR_MONITORING_CONFIGURATION."TRG_TRK_KPI_DEFINITION" 
    AFTER UPDATE ON RATOR_MONITORING_CONFIGURATION.KPI_DEFINITION FOR EACH ROW
    DECLARE
       PRAGMA AUTONOMOUS_TRANSACTION;
    BEGIN
      -- ...
      COMMIT; -- don't forget it!!!
    END;
    

    【讨论】:

    • 是的,我现在进行了更改,它显示了实际错误,错误是单行查询返回多行。
    • 多少行返回此查询:Select KPI_FREQ_TIME_UNIT FROM KPI_DEFINITION ?
    • 它返回不止一行。我已经解决了这个问题,但现在的问题是我有超过 50 个字段,如果我需要在每个 if 语句中提供提交?因为只要我声明 PRAGMA AUTONOMOUS_TRANSACTION 并且不提交,它就会给出错误,因为错误保存对表“RATOR_MONITORING_CONFIGURATION”的更改。“KPI_DEFINITION”:第 1 行:ORA-06519:检测到主动自主事务并回滚
    • 是的,在这种情况下你必须提交它......你有没有想过使用 DBMS_JOB 代替这个触发器?
    • 哦,好的。我只是在 END 之前的触发器底部添加提交,而不是在每个 if 语句中。它的工作,但它不会引起任何问题吗?
    【解决方案2】:

    由于您需要为其创建触发器的表中的信息(Select KPI_FREQ_TIME_UNIT FROM KPI_DEFINITION),您可以从参考 :NEW 中获取 KPI_FREQ_TIME_UNIT,因为它代表新行(:NEW.KPI_FREQ_TIME_UNIT)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-26
      • 2011-10-18
      • 2016-03-07
      • 2018-07-14
      • 2022-12-01
      • 2018-11-19
      • 2019-07-29
      • 2022-06-16
      相关资源
      最近更新 更多