Beachten Sie die folgenden erweiterten Kommentare:
Vielleicht liegt der Kern der Frage in einem Missverständnis darüber, was ein Cursor ist. Es ist kein Container voller Datensätze, es ist eine Spezifikation für eine Ergebnismenge, wie zu einem bestimmten Zeitpunkt, basierend auf einer einzigen SQL-Abfrage. Wenn Sie also
open rc for select id from table1;
und übergeben Sie rc
Zurück zum Aufrufer übergeben Sie keine Daten, sondern einen Zeiger auf einen privaten Speicherbereich, der eine vorbereitete Abfrage enthält. Sie pushen die Ergebnisse nicht, der Anrufer zieht sie. Es ist wie ein Programm, das der Aufrufer ausführt, um die Zeilen abzurufen. Sie können es nicht weiter öffnen, um eine weitere Zeile hinzuzufügen, was Sie meiner Meinung nach erhofft hatten.
Um eine Sammlung in einem Cursor innerhalb einer Prozedur zu verwenden, muss der Sammlungstyp als separates Schemaobjekt erstellt werden (obwohl Sie natürlich Sammlungstypen in anderen Prozeduren wiederverwenden können, also ist es nicht so restriktiv, wie es klingt).
Wenn Sie keinen Typ erstellen können, prüfen Sie, welche Typen bereits vorhanden sind und verwendet werden können:
select owner, type_name
from all_coll_types t
where t.coll_type = 'TABLE'
and t.elem_type_name = 'NUMBER';
Zum Beispiel:
create or replace type number_tt as table of number;
create table table1 (id primary key, currency, t_id) as
select 10, 'GBP', 'PB1' from dual union all
select 15, 'GBP', 'RB' from dual union all
select 20, 'GBP', 'CC' from dual union all
select 25, 'AUD', 'DC' from dual;
create table table2 (id,country,account) as
select 10, 'UK', 'PB1' from dual union all
select 15, 'Wales', 'RB' from dual union all
select 20, 'SH', 'CC' from dual;
Jetzt kann die Prozedur sein:
create or replace procedure myproc
( rc out sys_refcursor)
as
l_names number_tt;
begin
select id bulk collect into l_names
from table1
where currency = 'GBP';
open rc for
select t.id,t.country,t.account from table2 t
where t.id member of l_names;
end myproc;
Cursorausgabe:
ID COUNT ACC
---------- ----- ---
10 UK PB1
15 Wales RB
20 SH CC
(Ich habe die i_id
entfernt Parameter in Ihrer Prozedur, da mir nicht klar war, wie Sie ihn verwenden wollten.)
Vermutlich ist dies eine vereinfachte Version des eigentlichen Problems, denn so wie es aussieht, könnten Sie die erste Abfrage als Unterabfrage verwenden und würden die Sammlung nicht benötigen:
create or replace procedure myproc
( rc out sys_refcursor)
as
begin
open rc for
select t.id,t.country,t.account from table2 t
where t.id in
( select id
from table1
where currency = 'GBP' );
end myproc;
oder machen Sie einfach mit, wie Littlefoot vorgeschlagen hat:
create or replace procedure myproc
( rc out sys_refcursor)
as
begin
open rc for
select t2.id, t2.country, t2.account
from table1 t1
join table2 t2 on t2.id = t1.id
where t1.currency = 'GBP';
end myproc;
Sie haben jedoch zu dieser Antwort kommentiert, dass Sie dies nicht tun könnten, da Ihre Anforderung zu sein schien, dies über eine Sammlung, eine Schleife, etwas Klebeband, zwei Katzen und einen Fusionsgenerator zu tun.