我有一个表,participated
它有一个触发器,当新记录插入表中时,它返回驱动程序 ID 的总损坏量。
create or replace trigger display
after insert on participated
for each row
declare
t_id integer;
total integer;
begin
select driver_id, sum(damage_amount)
into t_id, total
from participated
where :new.driver_id = driver_id
group by driver_id;
dbms_output.put_line(' total amount ' || total' driver id' || t_id);
end;
/
触发器已创建,但返回此错误:
ORA-04091: table SQL_HSATRWHKNJHKDFMGWCUISUEEE.PARTICIPATED is mutating,
trigger/function may not see it ORA-06512: at
"SQL_HSATRWHKNJHKDFMGWCUISUEEE.DISPLAY", line 5
ORA-06512: at "SYS.DBMS_SQL", line 1721
请帮忙解决这个触发器。
如上所述,这感觉就像代码的味道。行级触发器不能更改正在更改的表,因为这会触发另一个触发器,这将导致调用触发器的无限循环。
将其更改为语句级触发器并不是在做同样的事情。
首选解决方案:1)将其放入应用程序逻辑,并在插入行后进行计算 - 正如@kfinity 提到的那样,这很简单。
2) 指定新插入的行并使用语句级触发器。例如,有一个额外的列,比如 is_new 默认 1 - 因此所有新插入的行都将具有此标志。然后使用@hbourchi 建议的语句级触发器计算并更新 is_new 为 1 的所有驱动程序,然后将此标志设置回零
3) 2) 中的逻辑可以使用 pl/sql 和内存中的 pl/sql 表来实现。pl/sql 表使用行级触发器收集受影响的驱动程序 ID,然后更新所选驱动程序的总数。Tom Kyte 在这方面有很多例子,这不是火箭科学,但是如果你缺乏 PL/SQL 知识,那么这可能不是你的方式。(对于注:PL / SQL是使用Oracle时超重要-不,甲骨文只是一个昂贵的Excel工作表像任何其他数据库使用它的价值。)
4)可能,您应该修改您的数据模型 - 问题会自行解决。在参加每个驱动器种类表显示多行。您想计算每个驱动程序 ID 的总行数 - 为什么要将汇总放在同一张表中?只需添加一个新表,parted_total,其中包含 driver_id 和 damage_amount 字段。然后按照您最初的计划随意从触发器插入或更新它!
5) 事实上,您可以通过在查询时简单地制作正确的 SQL 来即时计算这些总数(取决于行数和您的性能预期) - 这样就无需存储预先计算的总数。
6) 但如果您希望 Oracle 为您存储这些总计,您可以执行 5) 并使用物化视图。这些是实际表,由 Oracle 自动更新和维护,因此您在 5) 处的实际查询不需要即时计算任何内容,但可以从物化视图中获取自动预先计算的数据。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句