请注意以下扩展评论:
也许问题的核心是对光标是什么的误解。它不是一个装满记录的容器,而是基于单个 SQL 查询在某个时间点的结果集规范。所以如果你
open rc for select id from table1;
并通过rc
返回到调用者,您没有传递任何数据,而是传递一个指向包含准备好的查询的私有内存区域的指针。您不推送结果,而是调用者拉取结果。它就像调用者将执行以获取行的程序。您无法再打开它来添加另一行,我认为这正是您希望做的。
要在过程中的游标中使用集合,必须将集合类型创建为单独的架构对象(当然,您可以在其他过程中重用集合类型,因此它并不像听起来那么严格)。
如果您无法创建类型,请查看已有哪些类型可以使用:
select owner, type_name
from all_coll_types t
where t.coll_type = 'TABLE'
and t.elem_type_name = 'NUMBER';
例如:
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;
现在程序可以是:
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;
光标输出:
ID COUNT ACC
---------- ----- ---
10 UK PB1
15 Wales RB
20 SH CC
(我删除了i_id
参数在你的程序中,因为我不清楚你想如何使用它。)
据推测,这是实际问题的简化版本,因为就目前情况而言,您可以使用第一个查询作为子查询,并且不需要该集合:
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;
或者只是加入它,正如 Littlefoot 建议的那样:
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;
然而,您对这个答案评论说您不能这样做,因为您的要求似乎是通过一个集合、一个循环、一些胶带、两只猫和一个融合发生器来完成。