2010-01-21 46 views
2

我有这样的触发:该行级别触发器失败?

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)的合计值,通过在suming item_fornecimento的所有项目;我必须以不同的方式处理这种情况,如果是插入,就是更新。 触发器编译和所有,甚至一次,但它是唯一一个。我已经插入或在的SQLDeveloper更新了我的prec_total_if在item_fornecimento,但直到它由该触发器插入值替换订单的(fornecimento)总还是没有改变:(。

如果是很重要的,我f.total_enc_fornec它为空;它打印输出,但它似乎无法更新

回答

6

只要你知道:空+ 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; 
+0

Tks,我已经做到了。这是抢购的代价! – neverMind 2010-01-21 21:34:54

0

你的触发器将在多用户环境中失败,除非你在父级别执行某种序列化。

如果在周围item_fornecimento同一时间更新不同的行具有相同id_fornecimento两会上,fornecimento.total_enc_fornec会被错误地更新,因为每个会话不会看到其他会议上所作提交的更改。

为了解决这个问题,你可能会编写你的应用程序的代码,在更新/插入它的项目之前尝试对父记录fornecimento进行排它锁定。