我有这个表“function”,其中fk为自身(1:N),我需要检查行是否有一些坏循环。 我的想法是创建一个类似这样的触发器:
create or replace trigger FNZ_CHECK_PARENT after insert or update on FUNZIONE
For Each Row
Declare
cnt number;
Begin
Select CONNECT_BY_ISCYCLE "is_cycle"
Into cnt
From Funzione
Where Fnz_Parent Is Not Null
Connect By Nocycle Prior fnz_id = fnz_parent;
if cnt > 0
Then Raise_Application_Error(-20000, 'this is not allowed');
end if;
End;
但它不会出现此错误:
Errore SQL: ORA-04091: La tabella ACCERTA.FUNZIONE è in fase di modifica, il trigger/funzione non può leggerla
ORA-06512: a "ACCERTA.FNZ_CHECK_PARENT", line 4
ORA-04088: errore durante esecuzione del trigger 'ACCERTA.FNZ_CHECK_PARENT'
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.
有什么建议吗?
答案 0 :(得分:1)
FOR EACH ROW
触发器无法访问其定义的表。这就是Oracle的方式。
您可以做的是:在没有触发器的情况下插入行,然后对循环执行AFTER STATEMENT
触发器检查。
或者,您可以使用存储过程,而不是直接插入。当然,只有在你可以控制主叫方时才有效。
另一个想法是创建一个视图并制作一个“INSTEAD OF TRIGGER”,尽管如果它真的有效,我从未尝试过。
答案 1 :(得分:0)
这是尝试更改可变表。 Oracle(至少11.1)不允许这样做。 一个路由可以是触发器中的自治事务编译指示。另一个是在约束中实现这个逻辑(无论它是什么,因为你没有提供示例),oracle就是这样的。 在任何情况下,你的问题都是模棱两可的。