如何用主光标数据打开多个光标



我正在尝试读取从另一个存储过程返回的存储过程中的游标,并希望通过循环遍历主游标数据来写入多个输出游标。

-- TYPE myCursorType IS REF CURSOR;
PROCEDURE prcgetalldetails (
incustomernumber    IN customer.customer_number%TYPE,
accountdetailscur   OUT pkgaccount.curaccountdetailstype,
fundscur            OUT mycursortype,
otherdetailscur     OUT mycursortype
) IS
localaccountdetails   pkgaccount.curinvestmentaccount;
outcfunds             curinvestmentaccount;
accountdetails        pkgaccount.curaccountdetailstype%rowtype;
BEGIN
pkgaccount.accountdetails(incustomernumber,localaccountdetails);
LOOP
FETCH localaccountdetails INTO accountdetails;
EXIT WHEN localaccountdetails%notfound;
dbms_output.put_line(localaccountdetails.accountname
|| ','
|| localaccountdetails.accountnumber);

-- I have to return the 'accountdetailscur' as well,before that I have to loop through it and return remaining data as well
-- Based on account number I have to execute other queries and fetch other details and give those cursors back
OPEN fundscur FOR
SELECT
fundname,
fundid,
fundbalance
FROM
fundstable
WHERE
accountnumber = localaccountdetails.accountnumber;
OPEN otherdetailscur FOR
SELECT
col1,
col2
FROM
othertable
WHERE
accountnumber = localaccountdetails.accountnumber;
END LOOP;
END;

当我在循环中打开游标时,它将只返回localaccountdetails游标的最后一行详细信息。我不知道如何使用BUILK COLLECT来收集所有东西并在上面循环。

我不知道如何将localaccountdetails作为OUT数据返回&循环它以获得剩余的数据。

您可以使用游标表达式将一个游标嵌套在另一个游标中。这是形式:

select cursor ( select ... ) from ...

所以你可以这样做:

create table par ( pk primary key ) as 
select level pk
from   dual
connect by level <= 5;

create table chd as 
select r.c1 pk, par.pk fk 
from   par, lateral ( 
select level c1 from dual
connect by level <= pk
) r;

select pk,
cursor (
select * from chd c
where  par.pk = c.fk
)
from   par;
declare
cursor cur is 
select pk,
cursor (
select * from chd c
where  par.pk = c.fk
)
from   par;

pk      integer;
chd_cur sys_refcursor;
type chd_arr is table of chd%rowtype
index by pls_integer;
chd_recs chd_arr;
begin
open cur;
loop
fetch cur into pk, chd_cur;
exit when cur%notfound;

fetch chd_cur bulk collect into chd_recs;
dbms_output.put_line ( 
'Fetched ' || pk || ' child rows ' || chd_recs.count 
);
end loop;
close cur;
end;
/
Fetched 1 child rows 1
Fetched 2 child rows 2
Fetched 3 child rows 3
Fetched 4 child rows 4
Fetched 5 child rows 5

请注意,这意味着您正在滚动自己的嵌套循环联接。除非真的需要控制客户端从子表/内部表中获取的行数,否则我会将其作为联接。

如果您想确保从父表中获得一行,可以将内部表的行聚合为JSON或嵌套表,例如:

select par.pk,
json_arrayagg ( 
json_object ( chd.* ) 
)
from   par
join   chd
on     par.pk = chd.fk
group  by par.pk;
PK    JSON_ARRAYAGG(JSON_OBJECT(CHD.*))                                                   
1 [{"PK":1,"FK":1}]                                                                    
2 [{"PK":1,"FK":2},{"PK":2,"FK":2}]                                                    
3 [{"PK":1,"FK":3},{"PK":3,"FK":3},{"PK":2,"FK":3}]                                    
4 [{"PK":1,"FK":4},{"PK":4,"FK":4},{"PK":3,"FK":4},{"PK":2,"FK":4}]                    
5 [{"PK":1,"FK":5},{"PK":5,"FK":5},{"PK":4,"FK":5},{"PK":3,"FK":5},{"PK":2,"FK":5}]  

最新更新