我创建了一个检查COUNT的触发器。
create or replace
TRIGGER TEST_TRG before INSERT OR UPDATE ON TEST
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE
AVAILABLE INTEGER;
BEGIN
IF UPDATING THEN
IF(:new.STATUS = 600 OR :new.STATUS = 700) THEN
SELECT COUNT(1) INTO AVAILABLE FROM TEST T WHERE T.IDDISPLAY = :new.IDDISPLAY
AND T.STATUS NOT IN (600,700);
IF(AVAILABLE = 0) THEN
InsertOrUpdateAnotherTable(:new.IDDISPLAY, :new.STATUS, 0);
ELSE
RETURN;
END IF;
END IF;
END IF;
在测试表中将状态更改为600后,出现错误。
ORA-04091: table USER.TEST is mutating, trigger/function may not see it
ORA-06512: at "USER.TEST_TRG ", line 8
ORA-04088: error during execution of trigger 'USER.TEST_TRG'
如果符合条件,我将插入或更新另一个表。
错误是因为当触发器触发同一个表时,我尝试获取当前表的COUNT。这将导致发生变异。
我已尝试使用transaction_anonymous和Compound Trigger,但最后仍会出现相同的错误。
任何人都可以帮我解决另一个问题。
答案 0 :(得分:0)
首先:
以下这行
IF(AVAILABLE = 0) THEN
即使您可以消除变异错误,也永远无法达到。
像这样检查计数:COUNT(1)INTO AVAILABLE将抛出异常"没有找到数据"当你真的没有记录时,你会去查询。
其次: 使用compund触发器和AFTER EACH ROW部分可以避免变异,因为Tom写了http://www.dba-oracle.com/t_avoiding_mutating_table_error.htm:
试试这个:
create or replace
TRIGGER TEST_TRG FOR INSERT OR UPDATE ON TEST
COMPOUND TRIGGER
AVAILABLE INTEGER;
AFTER EACH ROW IS
BEGIN
IF UPDATING THEN
IF(:new.STATUS = 600 OR :new.STATUS = 700) THEN
BEGIN
SELECT COUNT(1) INTO AVAILABLE FROM TEST T WHERE T.IDDISPLAY = :new.IDDISPLAY
AND T.STATUS NOT IN (600,700);
EXCEPTION
WHEN NO_DATA_FOUND THEN
InsertOrUpdateAnotherTable(:new.IDDISPLAY, :new.STATUS, 0);
END;
END IF;
END IF;
END AFTER EACH ROW;
END TEST_TRG;