Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 此行级别触发器中失败的是什么?_Oracle_Plsql_Triggers - Fatal编程技术网

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,我已经这么做了。这是匆忙的代价!