Reputation: 35
I'm trying to create a procedure, that checks if two values are present in a table. The logic is as follows: Create a function called get_authority. This function takes two parameters (found in the account_owner table): cust_id and acc_id, and returns 1 (one), if the customer has the right to make withdrawals from the account, or 0 (zero), if the customer doesn't have any authority to the account. I'm writing plsql and using oracle live sql. I can't figure out how to handle the scenario where a customer has two accounts!
account_owner is seen here:
create or replace function get_authority(
p_cust_id in account_owner.cust_id%type,
p_acc_id in account_owner.acc_id%type
)
return varchar2
as
v_return number(1);
v_acc_id account_owner.acc_id%type;
v_cust_id account_owner.cust_id%type;
begin
for v_ in (select account_owner.cust_id,
account_owner.acc_id
from account_owner
where p_cust_id = cust_id)
LOOP
if p_cust_id = v_cust_id and p_acc_id = v_acc_id then
v_return := v_return + 1;
else
v_return := v_return + 0;
end if;
return v_return;
END LOOP;
end;
/
When I check for the cust_id I get the return 0 - but it should be 1??
select get_authority('650707-1111',123) from dual;
return:
GET_AUTHORITY('650707-1111',123)
0
What do I do wrong?
Upvotes: 0
Views: 923
Reputation: 142733
You got 0? How come; should be NULL.
v_return number(1);
so it is initially NULL. Later on, you're adding "something" to it, but - adding anything to NULL will be NULL:
SQL> select 25 + null as result from dual;
RESULT
----------
SQL>
Therefore, set its default value to 0 (zero):
v_return number(1) := 0;
Also, you declared two additional variables:
v_acc_id account_owner.acc_id%type;
v_cust_id account_owner.cust_id%type;
Then you compare them to values passed as parameters; as they are NULL, ELSE is executed.
Furthermore, there's a loop, but you don't do anything with it. If you meant that this:
for v_ in (select account_owner.cust_id,
(rewritten as for v_ in (select cust_id
) evaluates to v_cust_id
- it does not. Cursor variables are referred to as v_.cust_id
(note the dot in between).
Also, if there's only one row per p_cust_id
and p_acc_id
, why do you use cursor FOR loop at all? To avoid no_data_found
or too_many_rows
? I wouldn't do that; yes, it fixes such "errors", but is confusing. You'd rather properly handle exceptions.
Here's what you might have done:
Sample data:
SQL> select * From account_owner;
ACCOW_ID CUST_ID ACC_ID
---------- ----------- ----------
1 650707-1111 123
2 560126-1148 123
3 650707-1111 5899
Function; if there are more rows per parameters' combination, max
function will make sure that too_many_rows
is avoided (as it bothers you). You don't really care what it returns - important is that select
returns anything to prove that authority exists for that account.
SQL> create or replace function get_authority
2 (p_cust_id in account_owner.cust_id%type,
3 p_acc_id in account_owner.acc_id%type
4 )
5 return number
6 is
7 l_accow_id account_owner.accow_id%type;
8 begin
9 select max(o.accow_id)
10 into l_accow_id
11 from account_owner o
12 where o.cust_id = p_cust_id
13 and o.acc_id = p_acc_id;
14
15 return case when l_accow_id is not null then 1
16 else 0
17 end;
18 end;
19 /
Function created.
Testing:
SQL> select get_authority('650707-1111', 123) res_1,
2 get_authority('650707-1111', 5899) res_2
3 from dual;
RES_1 RES_2
---------- ----------
1 1
SQL>
Upvotes: 1