【问题标题】:Oracle Trigger on Table containing CLOB: ORA-04091: table is mutating, trigger/function may not see it包含 CLOB 的表上的 Oracle 触发器:ORA-04091:表正在变异,触发器/函数可能看不到它
【发布时间】:2014-07-15 01:24:22
【问题描述】:

您好,每当我尝试 SELECT(不更新/插入或进行任何更改)触发表时,我都会收到标题错误。如果我不选择 COB 列,我会让触发器工作,但是一旦我尝试使用 substr/instr 或 xmltype/extract 来获取内容,我就会收到错误。

SQL> SELECT version FROM V$INSTANCE;

VERSION
-----------------
11.2.0.3.0

SQL> desc alert;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ALERTID                                   NOT NULL VARCHAR2(32)
 JOBSTREAMRUNID                                     VARCHAR2(32)
 SEVERITY                                           VARCHAR2(32)
 STATUS                                             NUMBER(38)
 CREATIONTIME                                       FLOAT(126)
 DATAVALUES                                         CLOB
 ALERTTYPE                                          VARCHAR2(255)

触发器:

create or replace TRIGGER NEW_ALERT after insert on aedbadmin.alert for each row when severity='critical'
 DECLARE

 BEGIN

  insert into jawstemp (job_name,instance) 
  select xmltype(datavalues).extract('//TARGET_JOB_NAME/text()').getStringVal(),
  xmltype(datavalues).extract('//AUTOSYS_INSTANCE/text()').getStringVal() 
  from alert;
 END;
/

sqlldr 输出:

Record 1: Rejected - Error on table "ALERT".
ORA-04091: table AEDBADMIN.ALERT is mutating, trigger/function may not see it
ORA-06512: at "AEDBADMIN.NEW_ALERT", line 7
ORA-04088: error during execution of trigger 'AEDBADMIN.NEW_ALERT'

我也尝试将插入拆分为一个过程,但它只是解决了问题:

Record 1: Rejected - Error on table "ALERT".
ORA-04091: table AEDBADMIN.ALERT is mutating, trigger/function may not see it
ORA-06512: at "AEDBADMIN.NEW_ALERT_PROC", line 6
ORA-06512: at "AEDBADMIN.NEW_ALERT", line 3
ORA-04088: error during execution of trigger 'AEDBADMIN.NEW_ALERT'

不知道还能尝试什么..

请帮忙!

【问题讨论】:

  • 您真的要使用 INSERT 触发器 FOR EACH ROW 来查询所有记录并尝试插入另一个表吗?如果不是因为 mutating table 错误,您每次插入一行时都会插入所有记录。这似乎不太正确。
  • 谢谢。实际上,插入到jawstemp 表中的是一个占位符。工作时,它会在远程机器上执行一个 sp。另外,我取的两个xml字段只是整体的一小部分。

标签: oracle triggers clob


【解决方案1】:

触发码:

create or replace TRIGGER NEW_ALERT 
      after insert on aedbadmin.alert 
      for each row 
      when severity='critical'
    DECLARE

    BEGIN

      INSERT INTO jawstemp (job_name,instance) 
      VALUES (
             xmltype(:NEW.datavalues).extract('//TARGET_JOB_NAME/text()').getStringVal(),
             xmltype(:NEW.datavalues).extract('//AUTOSYS_INSTANCE/text()').getStringVal() 
      );
    END;
    /

【讨论】:

  • 感谢 MathCurious。我确实尝试过,它仍然得到同样的错误。事实证明我的触发器没有问题,问题是我的测试方法; sqlldr.
【解决方案2】:

原来问题是由于我使用 sql loader 来填充表和 CLOB。我想填充 CLOB 需要很长时间,甚至在触发器中休眠也没有用。如果我在不使用 sqlldr 的情况下将文本插入到 clob 列中,触发器就会起作用。

我希望实时喂食系统也不使用 sqlldr。

【讨论】:

    猜你喜欢
    • 2022-10-20
    • 2015-06-28
    • 2010-09-27
    • 2013-11-24
    • 2016-08-11
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    相关资源
    最近更新 更多