我有这个触发器:
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;
基本上我想通过对item_fornecimento中的所有项目进行求和来刷新订单的总价值(fornecimento);我必须以不同的方式对待它,例如它是一个插入,它是一个更新。 触发器编译,所有甚至工作一次,但它是唯一的。我已经在sqldeveloper中的item_fornecimento中插入或更新了我的prec_total_if,但订单的(fornecimento)总数仍未改变:(。
如果它很重要,我的f.total_enc_fornec它会为null,直到它被这个触发器插入的值替换掉;它打印输出,但似乎无法更新。
答案 0 :(得分:6)
大家知道: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;
答案 1 :(得分:0)
您的触发器将在多用户环境中失败,除非您在父级别实现某种序列化。
如果两个会话大约在同一时间更新item_fornecimento
中具有相同id_fornecimento
的不同行,则fornecimento.total_enc_fornec
将被错误地更新,因为每个会话都不会看到未提交的更改通过其他会议。
要解决此问题,您可能会编写应用程序,以便在更新/插入项目之前尝试对父fornecimento
记录进行独占锁定。