如何修复 ORA-04091:表正在变异,触发器/函数可能看不到它?
Posted
技术标签:
【中文标题】如何修复 ORA-04091:表正在变异,触发器/函数可能看不到它?【英文标题】:How do I fix ORA-04091: table is mutating, trigger/function may not see it? 【发布时间】:2020-08-20 15:51:27 【问题描述】:我想创建一个触发器,使同一行上的 trgr 的值等于 seq+100 的值。这就是我所做的,但我不断收到错误“表正在变异,触发器/函数可能看不到它”。
CREATE OR REPLACE TRIGGER update_tgr
AFTER INSERT ON challenge FOR EACH ROW
BEGIN
UPDATE challenge
SET trgr = :NEW.seq + 100
WHERE seq = :NEW.seq;
END;
我能做些什么来解决它?
【问题讨论】:
【参考方案1】:同一行?很简单:
CREATE OR REPLACE TRIGGER update_tgr
BEFORE INSERT ON challenge FOR EACH ROW
BEGIN
:NEW.trgr := :NEW.seq + 100;
END;
您知道您应该使用 BEFORE INSERT 触发器,因为这样您仍然可以操作新数据。
【讨论】:
您无法使用此触发器获得该错误。也许还有另一个触发错误的触发器? 我没有任何其他触发器 您真的删除了更新语句并用所示的简单赋值替换它吗? 是的。我试图用这个来激活它: INSERT INTO challenge VALUES ( 4, null ); seq 为 4,触发器为 null 如前所述,此触发器不会导致变异表错误。所以,正如你所说的没有其他触发器,一定是旧触发器没有被新触发器替换。【参考方案2】:如果您的数据库版本是 11g+,我认为创建 Virtual Column
是一个更好的选择。因为不需要在磁盘上存储已经可以计算的列。与传统定义样式不同,这可以防止为列 (trgr
) 插入错误值的可能性。然后,您可以重新创建表,例如
CREATE TABLE challenge (
.....
seq INT,
trgr AS (seq + 100), -- [VIRTUAL]
----
);
无需担心已经根据表达式结果确定的数据类型(INT
)。可以像普通表一样查询
【讨论】:
是的,这是更好的选择,只要触发器不仅仅是允许稍后更改的初始值。以上是关于如何修复 ORA-04091:表正在变异,触发器/函数可能看不到它?的主要内容,如果未能解决你的问题,请参考以下文章
ORA-04091: 表 JOSEP.EMP 正在变异,触发器/函数可能看不到它
ORA-04091: 表 [blah] 正在变异,触发器/函数可能看不到它
ORA-04091 表 ODB.EMPLOYEE 正在变异,触发器/函数可能看不到它。我的触发器有问题吗?
ORA-04091:表正在变异,触发器/函数可能看不到它,ORA-06512:,ORA-06512:在“SYS.DBMS_SQL”,第 1721 行