【问题标题】:Mutating table on Oracle SQL triggerOracle SQL触发器上的变异表
【发布时间】:2017-04-20 13:31:07
【问题描述】:

我正在尝试做一个触发器,但我得到一个变异表错误。 SQL 代码是这样的:

CREATE OR REPLACE TRIGGER CHK_Apartado_D
BEFORE INSERT OR UPDATE ON CONTRACTS
FOR EACH ROW
DECLARE 
errorvisualizacion EXCEPTION;
local_enddate DATE;
BEGIN
  SELECT enddate INTO local_enddate FROM CONTRACTS WHERE clientid=:new.clientid;
  IF local_enddate > SYSDATE OR local_enddate IS NULL
  THEN 
    UPDATE CONTRACTS SET enddate = SYSDATE - 1 WHERE clientid=:new.clientid;
  END IF;
END CHK_Apartado_B;
/

我得到的错误是:

Informe de error -
Error SQL: ORA-04091: table HR.CONTRACTS is mutating, trigger/function may not see it
ORA-06512: at "HR.CHK_APARTADO_D", line 5
ORA-04088: error during execution of trigger 'HR.CHK_APARTADO_D'
ORA-06512: at "HR.CHK_APARTADO_D", line 8
ORA-04088: error during execution of trigger 'HR.CHK_APARTADO_D'
04091. 00000 -  "table %s.%s is mutating, trigger/function may not see it"
*Cause:    A trigger (or a user defined plsql function that is referenced in
           this statement) attempted to look at (or modify) a table that was
           in the middle of being modified by the statement which fired it.
*Action:   Rewrite the trigger (or function) so it does not read that table.

当我插入新合同时,我必须检查该客户在实际日期是否有其他合同,如果他有,我必须将 de end date contracte 更新到昨天并让新的 INSERT。那么,如何防止变异表呢?

【问题讨论】:

  • 这似乎是一个最近让一些人感到困惑的练习:。 hereherehere;哦,去年的这个时候也是,here,...
  • @AlexPoole - 似乎我们需要一个规范的答案,并继续关闭重复。
  • @APC - 是一个规范的答案,它将有效地成为适当的分配答案?尽管我不确定我是否在任何地方看到过以暗示分配者实际正在寻找的答案的方式陈述的作业......或者至少不是我很乐意尝试写的答案 *8-)

标签: sql oracle triggers


【解决方案1】:

您的触发器在更新或插入 CONTRACTS 时触发,然后尝试更新触发触发器的 CONTRACTS.... 看到问题了吗?

您需要计算出结束日期,然后实际执行插入/更新。

【讨论】:

    【解决方案2】:

    一个常见的解决方案是Using Compound Triggers to Avoid Mutating-Table Error

    最好不要尝试使用触发器来实现复杂的业务逻辑。相反,使用实现业务规则的过程insert_contract 构建 API 包,并确保(通过特权)用户调用该 API,而不是直接插入到表中。触发器会很快变得非常混乱。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-09
      • 2013-10-03
      • 1970-01-01
      • 2021-05-21
      相关资源
      最近更新 更多