Posidon
Posidon

Reputation: 35

Call a function within a trigger in pl/sql

I've searched through the Internet for some resource providing me with an example of how to call a function I've created from within a trigger in PL/SQL.

I've made a function called get_balance that looks like this:

create or replace function get_balance(p_custno in number)
return number
as
v_balance account.balance%type;
begin
select balance 
into v_balance
from account
where custno = p_custno;
return v_balance;
end;
/

Now I want to call this function from within a trigger to check the balance before a withdrawal. I tried to do it as follows but I think it's totally wrong:

create or replace trigger bifer_withdrawal
before insert on withdrawal
for each row
begin
if get_balance(p_custno) <= amount then
raise_application_error(-20001, 'Not enough money in account!');
end if;
end;
/

Could someone please provide a newbie with an example of how to call a function from within a trigger?

Upvotes: 0

Views: 19755

Answers (1)

Ollie
Ollie

Reputation: 17538

You need to specify the value for p_custno I have used the default NEW alias but see here for trigger information, also René Nyffenegger's has a good explanation of the NEW and OLD usage:

create or replace 
trigger bifer_withdrawal 
before insert on withdrawal 
for each row 
begin
   if get_balance(:NEW.custno) <= amount 
   then
      raise_application_error(-20001, 'Not enough money in account!');
   end if;
end; 
/

You will need to specify what AMOUNT is too. If it is a variable then declare it between the FOR EACH ROW and BEGIN statements:

e.g.:

create or replace 
trigger bifer_withdrawal 
before insert on withdrawal 
for each row 
declare
   c_amount CONSTANT account.balance%TYPE := 5000; -- Whatever limit you need
begin
   if get_balance(:NEW.custno) <= c_amount 
   then
      raise_application_error(-20001, 'Not enough money in account!');
   end if;
end; 
/

You should ask yourself, do you need to call the function?
You could easily wrap the cursor into the trigger and save yourself the function call.
Your answer will depend upon issues around whether you want to reuse the function elsewhere etc.
I'm not advocating one way over the other but it is something to consider.

Hope it helps...

EDIT: After the two comments below, if AMOUNT is a column in the table WITHDRAWAL then:

create or replace 
trigger bifer_withdrawal 
before insert on withdrawal 
for each row 
begin
   if get_balance(:NEW.custno) <= :NEW.amount
   then
      raise_application_error(-20001, 'Not enough money in account!');
   end if;
end; 
/

Upvotes: 3

Related Questions