Oracle - 触发器中发生变异 Table 异常?

Oracle - Getting Mutating Table Exception in trigger?

我想编写一个触发器,在插入 table 之前进行检查,以查看 table 中是否存在具有相同 fk_id 和 [=15= 的条目].例如想象以下 table:

| row_id | fk_id |  active_flag |
| ------------------------------|
|    1   |   500 |         1    |
|    2   |   500 |         0    |
|    3   |   501 |         1    |

假设我想用 fk_id = 500active_flag = 1 插入一个新行。我想抛出一个例外,因为根据我的规则,你不能有两行具有相同的 fk_id 并且在这个 table 中也是 active任何给定时间。

我写了一个触发器来尝试处理这个问题:

CREATE OR REPLACE TRIGGER MYSCHEMA.CHECK_DUPS_BIU

BEFORE INSERT OR UPDATE ON MYSCHEMA.MYTABLE_T FOR EACH ROW
DECLARE
    l_cnt NUMBER;
    e_dup EXCEPTION;
BEGIN

    SELECT COUNT(*)
    INTO l_cnt
    FROM MYSCHEMA.MYTABLE_T 
    WHERE fk_id = :new.fk_id
    AND active_flag > 0;

    IF(l_cnt > 0)
    THEN
        RAISE e_dup;
    END IF;

EXCEPTION 
 WHEN e_dup THEN
  raise_application_error(-20300, 'You cannot insert two active items with the same fk_id');
END CHECK_DUPS_BIU;
/

有了这个触发器,它在插入时完全可以正常工作,但是当我进行更新时,我得到了一个突变 table 异常:

ORA-04091: table MYSCHEMA.CHECK_DUPS_BIU is mutating, trigger/function may not see it
ORA-06512: at "MYSCHEMA.CHECK_DUPS_BIU ", line 12
ORA-04088: error during execution of trigger 'MYSCHEMA.CHECK_DUPS_BIU '

我对这个问题做了一些研究,我读到处理这种情况的更好方法 * 可能是使用约束代替,但我不确定如何编写这样一个检查另一个约束的代码列(active_flag)。

如何执行这样的检查?

不要使用触发器,使用基于 UNIQUE 函数的索引:

create unique index myindex on mytable (case when active_flag=1 then fk_id end);

当active_flag不为1时,索引中不会存储任何条目;当 active_flag 为 1 时,将存储一个条目 - 但如果相同的 fk_id 已经存在,则会引发异常。