我有两个表,PRODUCTS和STATE_PRICE。每种产品的价格因州而异。 PRODUCTS表跟踪所有州的每种产品的平均成本。我正在尝试编写一个触发器,当在STATE_PRICE表中插入,更新或删除价格时,该触发器将更新PRODUCTS表中项目的平均价格。我编写了以下触发器,它编译,但当我测试它时,我得到一个变异的错误消息。我理解变异错误的概念,我正在尝试更新正在执行触发器的表,但我实际上是在STATE_PRICE表上执行触发器时尝试更新PRODUCTS表。
create or replace trigger trg_avg_cost
after insert or update or delete on state_price
for each row
declare
w_price state_price.list_price%type;
w_product state_price.productid%type;
begin
w_price := :new.list_price;
w_product := :new.productid;
update products
set avg_cost_per_unit = (select avg(w_price) from state_price
where productid = w_product);
end;
/
我得到的具体错误消息是:
错误报告:
SQL Error: ORA-04091: table STATE_PRICE is mutating, trigger/function may not see it
ORA-06512: at "TRG_AVG_COST", line 9
ORA-04088: error during execution of trigger 'TRG_AVG_COST'
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 :(得分:0)
可能存在参照完整性约束(在产品ID上),这也可能引发相同的错误。如果是这种情况,以下链接可以帮助您避免错误。
http://asktom.oracle.com/pls/asktom/ASKTOM.download_file?p_file=6551198119097816936
答案 1 :(得分:0)
在行触发器中,没有SQL语句可以访问触发器所在的表。您的SELECT AVG(W_PRICE) FROM STATE_PRICE WHERE PRODUCTID = W_PRODUCT
是造成错误的原因。解决此限制的经典方法是使用复合触发器 - 文档here。另请参阅我对this StackOverflow question的回答,了解实现复合触发器的示例。
分享并享受。