Oracle 此行级别触发器中失败的是什么?
我有一个触发器:Oracle 此行级别触发器中失败的是什么?,oracle,plsql,triggers,Oracle,Plsql,Triggers,我有一个触发器: create or replace trigger t_calctotal after insert or update on item_fornecimento REFERENCING NEW AS NEW OLD AS OLD for each row begin if inserting then dbms_output.put_line(' On Insert'); update fornecimento f set f.total_enc_fornec
create or replace trigger t_calctotal
after insert or update on item_fornecimento
REFERENCING NEW AS NEW OLD AS OLD
for each row
begin
if inserting then
dbms_output.put_line(' On Insert');
update fornecimento f set f.total_enc_fornec = f.total_enc_fornec +:NEW.prec_total_if where f.id_fornecimento = :NEW.id_fornecimento;
else
dbms_output.put_line(' On Update');
update fornecimento f set f.total_enc_fornec = f.total_enc_fornec - :OLD.prec_total_if +:NEW.prec_total_if where f.id_fornecimento = :NEW.id_fornecimento;
end if;
end;
基本上,我想刷新订单(fornecimento)的总价值,方法是汇总item_fornecimento中的所有项目;我必须用不同的方式来处理这个问题,如果是插入,如果是更新。
触发器编译了所有代码,甚至工作了一次,但它是唯一的一个。我已经在sqldeveloper中的项目fornecimento中插入或更新了我的prec_total,但订单的(fornecimento)总计仍然没有更改:(
如果很重要,我的f.total\u enc\u fornec在被该触发器插入的值替换之前是空的;它打印输出,但似乎更新失败。正如您所知:null+123=null 我想这就解释了。将总数初始化为0,一切都应该正常 编辑 您可以这样做:
if inserting then
dbms_output.put_line(' On Insert');
update fornecimento f set f.total_enc_fornec = nvl(f.total_enc_fornec, 0) +:NEW.prec_total_if where f.id_fornecimento = :NEW.id_fornecimento;
else
dbms_output.put_line(' On Update');
update fornecimento f set f.total_enc_fornec = nvl(f.total_enc_fornec, 0) - :OLD.prec_total_if +:NEW.prec_total_if where f.id_fornecimento = :NEW.id_fornecimento;
end if;
除非在父级实现某种序列化,否则触发器将在多用户环境中失败 如果两个会话几乎同时更新
项\u forneciento
中具有相同id\u forneciento
的不同行,则forneciento.total\u enc\u fornec
将被错误更新,因为每个会话都不会看到其他会话所做的未提交更改
要解决这个问题,您可能需要编写应用程序代码,在更新/插入父项之前尝试对父项
forneciento
记录进行独占锁定。Tks,我已经这么做了。这是匆忙的代价!