Reputation: 71
Hi I have this trigger
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;
Which compiles properly but when an insertion is done on the table nbty_customer like for example
insert into nbty_customer values('2','abc','200')
It throws ora-01403 no data found error,ora-04088 error during execution of trigger Kindly help, I am not able to figure out what the issue is?
Upvotes: 1
Views: 4793
Reputation: 71
The problem was due to a select into
clause which returned a 'no data found' so I removed the select into
and directly used a bind variable instead:
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;
This solved the problem.
Upvotes: 2
Reputation: 30845
In your trigger body, you're trying to select the data of your new row:
SELECT :NEW.cust_sal-:OLD.cust_sal INTO V_REQ FROM nbty_customer where cust_id=:old.cust_id;
But you declared your trigger body as PRAGMA AUTONOMOUS_TRANSACTION
. Therefore, your trigger does not see the changes that triggered the trigger execution in the first place.
Using AUTONOMOUS_TRANSACTION
in triggers is never a good idea; see Tom Kyte on Triggers for a detailed explanation on why you want to avoid this.
If you need to cache your data for performance reasons, I'd recommend using a Materialized View instead. You can set it to REFRESH ON COMMIT
if needed:
create materialized view mv_cache
refresh on commit
as
select distinct cust_id cust_id, cust_name cust_name, V_REQ
from nbty_customer
Upvotes: 0
Reputation: 157136
I just commented, and then I noticed this:
select :NEW.cust_sal+:OLD.cust_sal INTO V_REQ FROM nbty_customer
where cust_id=:old.cust_id;
On insert
, this select
will fail since there is no :old.cust_id
. Use :new.cust_id
instead. (also, :old.cust_sal
will be null too)
Upvotes: 1