Reputation: 779
I have created an oracle function that returns SYS_REFCURSOR. The issue is that data which I need to return may be produced by two different queries. Basically if first query returns no data then I need to run a different query and then return refcursor.
Here is my big idea
FUNCTION F_RETURN_RECORD(
P_VAL in NUMBER)
RETURN SYS_REFCURSOR AS TYPE R_CURSOR IS REF CURSOR;
my_record_1 R_CURSOR;
processed_record R_CURSOR;
BEGIN
OPEN my_record_1 FOR select e.COL1, e.COL2,a.COL1,e.COL3, e.COL4,
e.COL5, e.COL6, e.COL7, e.COL8, e.COL9,
e.COL10, e.COL11
from table1 e
inner join table2 a on e.COL2=a.COL2
where e.COL1=P_VAL;
if my_record_1%notfound
then
close my_record_1;
OPEN processed_record for select e.COL1, e.COL2,a.COL1,e.COL3, e.COL4,
e.COL5, e.COL6, e.COL7, e.COL8, e.COL9,
e.COL10, e.COL11, e.COL12, e.COL13, e.COL14
from table3 e
inner join table2 a on e.COL2=a.COL2
inner join table 4 b on a.col1=b.col2
where e.COL1=P_VAL;
return processed_record;
end if;
DBMS_OUTPUT.PUT_LINE('Returning data.................');
return my_record_1;
END F_RETURN_RECORD;
For whatever reason if my_record_1%notfound
check doesn't work. I guess my question is how can I check if my_record_1 cursor doesn't contain any data?
Thank you
Upvotes: 2
Views: 3372
Reputation: 230
I think you can simplify the whole code by just using FOR loop instead of using %NOTFOUND. This is an example of this sample code you can try.
CREATE OR REPLACE FUNCTION F_RETURN_RECORD(
P_VAL IN NUMBER)
RETURN SYS_REFCURSOR
AS
TYPE R_CURSOR
IS
REF
CURSOR;
my_record_1 R_CURSOR;
processed_record R_CURSOR;
cur_count NUMBER;
BEGIN
cur_count:=0;
--OPEN my_record_1 FOR select * FROM AVRAJIT;
FOR rec IN
(SELECT query
)
LOOP
cur_count:=cur_count+1;
END LOOP;
--if my_record_1%notfound
--then
-- close my_record_1;
IF cur_count <> 1 THEN
OPEN processed_record FOR SELECT query;
RETURN processed_record;
END IF;
DBMS_OUTPUT.PUT_LINE('Returning data.................');
RETURN my_record_1;
END F_RETURN_RECORD;
Upvotes: 0
Reputation: 2021
I noticed some common features of the two queries used in the procedure:
Cursor query option 1:
select e.COL1, e.COL2,a.COL1,e.COL3, e.COL4,
e.COL5, e.COL6, e.COL7, e.COL8, e.COL9,
e.COL10,e.COL11, e.COL12, e.COL13, e.COL14
from table1 e
where e.COL1=P_VAL;
inner join table2 a on e.COL2=a.COL2
table1
must have similar structure totable3
because both are used identically in the two different queries.
Cursor query option 2:
select e.COL1, e.COL2,a.COL1,e.COL3, e.COL4,
e.COL5, e.COL6, e.COL7, e.COL8, e.COL9,
e.COL10,e.COL11, e.COL12, e.COL13, e.COL14
from table3 e
where e.COL1=P_VAL;
inner join table2 a on e.COL2=a.COL2
inner join table4 b on a.col1=b.col2
If no results come back from option 1 (no data found), this query (option 2) is used. It differs by the primary table queried (
table3
) and an additional INNER JOIN totable4
is added.
FUNCTION F_RETURN_RECORD (P_VAL IN NUMBER) RETURN SYS_REFCURSOR AS TYPE R_CURSOR
IS REF CURSOR;
my_record_1 R_CURSOR;
processed_record R_CURSOR;
BEGIN
OPEN my_record_1 FOR
WITH
OPT1 AS (SELECT e.col1, e.col2, e.col3, e.col4, ..., e.col14
FROM table1 e
INNER JOIN table2 a on e.col2 = a.col2
WHERE e.col1 = P_VAL),
OPT2 AS (SELECT e.col1, e.col2, e.col3, e.col4, ..., e.col14
FROM table1 e
INNER JOIN table2 a on e.col2 = a.col2
INNER JOIN table4 b on a.col1 = b.col2
WHERE e.col1 = P_VAL),
SELECT NVL(opt1.col1, opt2.col1) as col1,
NVL(opt1.col2, opt2.col2) as col2,
NVL(opt1.col3, opt2.col3) as col3,
NVL(opt1.col4, opt2.col4) as col4,
....
NVL(opt1.col3, opt2.col3) as col13,
NVL(opt1.col4, opt2.col4) as col14
FROM OPT2
LEFT OUTER JOIN OPT1 on OPT2.col1 = OPT1.col1;
return my_record_1;
END F_RETURN_RECORD;
I could also see how a UNION or UNION ALL operator might have also served the result. In my approach, I leveraged
JOINS
to manage the results.
Upvotes: 2