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 = 500
和 active_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 已经存在,则会引发异常。
我想编写一个触发器,在插入 table 之前进行检查,以查看 table 中是否存在具有相同 fk_id
和 [=15= 的条目].例如想象以下 table:
| row_id | fk_id | active_flag |
| ------------------------------|
| 1 | 500 | 1 |
| 2 | 500 | 0 |
| 3 | 501 | 1 |
假设我想用 fk_id = 500
和 active_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 已经存在,则会引发异常。