'I am building my first function in PLSQL, it needs to return a single summed value of spending by a user based off parameters username and fiscal year
The function compiles, but when I run this block:
select sumyUserSpending('ALCraft', 15) from infor.credit_card_transaction
It throws error ORA-06575: Package or function sumyuserspending is in an invalid state.
When I run this block:
declare
answer number;
begin
answer := sumyUserSpending('ALCraft', 15);
dbms_output.put_line(answer);
end;
It throws errors ORA-65550 and PLS-00905: object sumyuserspending is invalid.
Here is my function. When I only run the function, it throws no errors, so I am lost as to what it could need to run smoothly. When the query is taken out of the function and I run the query alone, it returns the value I want based on the placeholder values I put in for the parameters. I am working in oracle 12c.
create or replace function sumyUserSpending (userN in varchar2, fiscYear in number)
return number
is
total number;
cursor search1 is
select sum(infor.credit_card_transaction.due_cc_co_amount) into total from infor.credit_card_transaction
inner join infor.credit_card using (credit_card_id)
inner join infor.ext_user using (user_id)
where infor.credit_card_transaction.transaction_date > concat('01-JUL-', (fiscYear - 1))
and infor.credit_card_transaction.transaction_date < concat('30-JUNE-', fiscYear)
and NVL(SUBSTR(infor.ext_user.email_address, 0, INSTR(infor.ext_user.email_address, '@')-1), infor.ext_user.email_address) = userN;
begin
open search1
fetch search1 into total;
if search1%notfound then
total := 0;
end if;
close search1;
return total;
end;
Solution 1:[1]
- You need to refer to the tables by their just table name or an alias outside the
FROMclause and not byschema_name.table_name. - Do not rely on implicit conversion of strings to dates; explicitly convert them using
TO_DATE. - If you are using a cursor then a
INTOclause is not syntactically valid. - However, you do not need a cursor.
Fixing all that gives you:
create or replace function sumyUserSpending (
userN in ext_user.email_address%TYPE,
fiscYear in number
) RETURN number
IS
total number;
BEGIN
select COALESCE(sum(cct.due_cc_co_amount), 0)
into total
from infor.credit_card_transaction cct
inner join infor.credit_card cc using (credit_card_id)
inner join infor.ext_user eu using (user_id)
where cct.transaction_date >= TO_DATE((fiscyear - 1) || '07-01', 'RR-MM-DD')
and cct.transaction_date < TO_DATE(fiscyear || '07-01', 'RR-MM-DD')
and NVL(SUBSTR(eu.email_address, 0, INSTR(eu.email_address, '@')-1), eu.email_address)
= userN;
return total;
end;
/
db<>fiddle here
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
