ora-01403未找到数据错误,执行触发时出现ora-04088错误

时间:2014-04-30 14:21:51

标签: oracle plsql

嗨,我有这个触发器

create or replace TRIGGER trg_cust
after insert or update on nbty_customer
referencing old as old new as new
for each row
declare
pragma autonomous_transaction;
V_REQ VARCHAR2(10);
begin 

 IF(:NEW.cust_sal<1000)
        THEN
        select :NEW.cust_sal+:OLD.cust_sal INTO V_REQ FROM nbty_customer
        where cust_id=:old.cust_id;

    ELSE
    SELECT :NEW.cust_sal-:OLD.cust_sal INTO V_REQ FROM nbty_customer where cust_id=:old.cust_id;
    end if;

merge into nbty_cache_cust 
    using
       (select distinct :new.cust_id cust_id, :new.cust_name cust_name,V_REQ V_REQ
       from nbty_customer) b
       on (cust_nbty_id = b.cust_id)
        when matched then
       update set cust_nbty_name = b.cust_name, cust_nbty_sal = b.V_REQ 
       when not matched then
      insert (cust_nbty_id, cust_nbty_name, cust_nbty_sal)
      values (b.cust_id, b.cust_name, b.V_REQ);
      commit;
      end;

哪个编译正确,但是当在表nbty_customer上进行插入时,例如

insert into nbty_customer values('2','abc','200')

它抛出ora-01403没有发现数据错误,执行触发器时出现ora-04088错误 请帮助,我无法弄清楚问题是什么?

3 个答案:

答案 0 :(得分:2)

问题是由于select into子句返回“未找到数据”所以我删除了select into并直接使用了绑定变量:

IF(:new.cust_sal<1000)
then
  v_req:=nvl(:new.cust_sal,0)+nvl(:old.cust_sal,0);
else
  v_req:=nvl(:new.cust_sal,0)-nvl(:old.cust_sal,0);
end if;

这解决了这个问题。

答案 1 :(得分:1)

我刚评论过,然后我注意到了这一点:

select :NEW.cust_sal+:OLD.cust_sal INTO V_REQ FROM nbty_customer
    where cust_id=:old.cust_id;

insert上,此select将失败,因为没有:old.cust_id。请改用:new.cust_id。 (另外,:old.cust_sal也将为空)

答案 2 :(得分:0)

在您的触发器正文中,您正在尝试选择新行的数据:

 SELECT :NEW.cust_sal-:OLD.cust_sal INTO V_REQ FROM nbty_customer where cust_id=:old.cust_id;

但是您将触发器主体声明为PRAGMA AUTONOMOUS_TRANSACTION。因此,您的触发器不会首先看到触发触发器执行的更改。

在触发器中使用AUTONOMOUS_TRANSACTION 从不一个好主意;请参阅Tom Kyte on Triggers,详细说明您为什么要避免这种情况。

如果出于性能原因需要缓存数据,我建议您使用实体化视图。如果需要,您可以将其设置为REFRESH ON COMMIT

create materialized view mv_cache
refresh on commit 
as 
select distinct cust_id cust_id, cust_name cust_name, V_REQ 
from nbty_customer