执行触发器时出现错误(ORA-04091:表 DBPROJEKT_AKTIENDEPOT.AKTIE 正在发生变化,触发器/函数可能看不到它):
CREATE OR REPLACE TRIGGER Aktien_Bilanz_Berechnung
AFTER
INSERT OR UPDATE OF TAGESKURS
OR INSERT OR UPDATE OF WERT_BEIM_EINKAUF
ON AKTIE
FOR EACH ROW
DECLARE
bfr number;
Begin
bfr := :new.TAGESKURS - :new.WERT_BEIM_EINKAUF;
UPDATE AKTIE
SET BILANZ = TAGESKURS - WERT_BEIM_EINKAUF;
IF bfr < -50
THEN
DBMS_OUTPUT.PUT_LINE('ACHTUNG: The value (Nr: '||:new.AKTIEN_NR||') is very low!');
END IF;
END;
我想在计算后检查值“BILANZ”,它是否低于-50。
您知道为什么会引发此错误吗?
谢谢你的帮助!
这里有几个问题:
Oracle 不允许您在该表上定义的行触发器或从此类触发器调用的任何代码中对该表执行 SELECT/INSERT/UPDATE/DELETE,这就是运行时发生错误的原因。有很多方法可以解决这个问题 - 例如,您可以阅读我的回答这个问题 https://stackoverflow.com/questions/29489951/oracle-trigger-after-insert-or-delete and 这个问题 https://stackoverflow.com/questions/25917291/pl-sql-trigger-gets-a-mutating-table-error- 但一般来说,您必须避免从触发器内访问定义了行触发器的表。
在此触发器中执行的计算称为商业逻辑并且不应在触发器中执行。将这样的逻辑放入触发器中,无论看起来多么方便,最终都会让任何必须维护此代码的人感到非常困惑,因为BILANZ
被更改的地方是正在阅读应用程序代码的人INSERT
or UPDATE
声明看不到。该计算应在INSERT
or UPDATE
语句,不在触发器中。定义一个过程来对表执行 INSERT/UPDATE/DELETE 操作被认为是一种很好的做法,以便可以在一个地方捕获所有此类计算,而不是分散在整个代码库中。
在 BEFORE ROW 触发器内can修改中字段的值:NEW
row 变量用于在将值写入数据库之前更改值。有时这是可以接受的,例如设置跟踪行最后更改时间和修改者的列,但一般来说,这被认为是一个坏主意。
祝你好运。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)