Oracle11g 合并两个sys\u refcursor的输出
我在Oracle11g中有两个函数,它们返回一个sys\u refcursos。 第一个Oracle11g 合并两个sys\u refcursor的输出,oracle11g,merge,cursor,Oracle11g,Merge,Cursor,我在Oracle11g中有两个函数,它们返回一个sys\u refcursos。 第一个 create or replace FUNCTION num_gettoni (cf_parlamentare IN parlamentari.cf %TYPE DEFAULT 'MRTMRZ' --, num_legislatura in legislature.id%TYPE ) RETURN SYS_REFCURSOR AS my_cursor SYS_REFC
create or replace FUNCTION num_gettoni
(cf_parlamentare IN parlamentari.cf %TYPE DEFAULT 'MRTMRZ'
--, num_legislatura in legislature.id%TYPE
) RETURN SYS_REFCURSOR
AS
my_cursor SYS_REFCURSOR;
pippo legislature.id%type;
BEGIN
OPEN my_cursor FOR
select
leg,
ct as gettoni
from(
SELECT
l.id AS leg,
COUNT(*) - lead(COUNT(*), 1, 0) over (order by l.datainizio) AS ct
FROM
legislature l,
partecipazioni i,
parlamentari p
WHERE
i.sedute_data >= l.datainizio
AND p.cf = i.parlamentare
AND p.cf = cf_parlamentare
group by l.datainizio, l.id
)
where ct > 0
order by ct desc;
/*open my_cursor;
loop
pippo := my_cursor.leg;
END LOOP;
end loop;*/
RETURN my_cursor;
END num_gettoni;
第一个funzion的输出示例如下
select num_gettoni('MRTMRZ') from dual;
NUM_GETTONI('MRTMRZ')
---------------------
LEG GETTONI
---------------------- ----------------------
17 3
18 2
第二个函数类似,第二个函数的输出为
select num_interrogazioni('MRTMRZ') from dual;
NUM_INTERROGAZIONI('MRTMRZ')
--------------------------------------
LEG INTERROGAZIONI
---------------------- ----------------------
18 1
是否可以通过一个过程调用这些函数,并在下面得到类似的结果
NUM_INTERROGAZIONI('MRTMRZ')
--------------------------------------
LEG GETTONI INTERROGAZIONI
---------------------- ---------------------- ----------------------
17 3
18 2 1
没有简单的内置机制来合并ref游标;它们本质上是指向结果集的指针,它们不能被视为表,因此它们不能被连接,这就是您在这里试图实现的 如果只想显示组合结果,可以使用PL/SQL集合存储第一个ref游标的结果,然后根据
leg
作为公共“键”值,使用第二个ref游标的结果对其进行更新/添加:
declare
-- for the collection
type t_rec is record (leg number, gettoni number, interrogazioni number);
type t_tab is table of t_rec index by pls_integer;
l_tab t_tab;
-- for the cursors returned by the functions
l_cursor sys_refcursor;
-- for the individual columns from the cursors
l_leg number;
l_gettoni number;
l_interrogazioni number;
begin
l_cursor := num_gettoni('MRTMRZ');
loop
fetch l_cursor into l_leg, l_gettoni;
exit when l_cursor%notfound;
l_tab(l_leg).leg := l_leg;
l_tab(l_leg).gettoni := l_gettoni;
end loop;
close l_cursor;
l_cursor := num_interrogazioni('MRTMRZ');
loop
fetch l_cursor into l_leg, l_interrogazioni;
exit when l_cursor%notfound;
l_tab(l_leg).leg := l_leg;
l_tab(l_leg).interrogazioni := l_interrogazioni;
end loop;
close l_cursor;
for i in l_tab.first..l_tab.last loop
dbms_output.put_line(l_tab(i).leg ||','|| l_tab(i).gettoni ||','|| l_tab(i).interrogazioni);
end loop;
end;
/
使用返回所显示结果的伪函数,可以获得:
17,3,
18,2,1
PL/SQL procedure successfully completed.
两个游标循环本质上是相同的。调用相关函数并在结果上循环,在index by collection元素中为游标拥有的列设置值;其中,在这两种情况下,索引都是leg
值
第一个循环填充索引17和18处记录元素的leg
和gettoni
值。第二个只看到18的结果,并为该元素设置interrogazioni
。如果它也有一个不同的leg
,比如说19,那么它也会用leg
和interrogazioni
值填充一个索引元素。(因此,本质上,它大致相当于一个完整的外部连接…)
但是依靠dbms\u输出
进行输出并不理想,因为您无法控制客户机是否在使用它,而且更难格式化和使用它。将结果作为可在查询中使用的表集合或作为新的ref游标返回可能更有用
您可以使用一个包来定义集合类型,其中一个函数使用上面的机制将结果作为表集合输出,另一个函数从该管道表生成一个ref游标:
create or replace package p42 as
type t_rec is record (leg number, gettoni number, interrogazioni number);
type t_tab is table of t_rec;
-- function for pipelined table collection
function num_combo_tab (p_param varchar2) return t_tab pipelined;
-- function for ref cursor
function num_combo_cur (p_param varchar2) return sys_refcursor;
end p42;
/
这里的num\u combo\u tab
基本上是上面的匿名块,但它通过管道传输记录类型,而不是使用dbms\u输出
。然后,num\u combo\u cur
只为该结果打开一个ref光标
那么你可以做:
select p42.num_combo_cur('MRTMRZ') from dual;
P42.NUM_COMBO_CUR('M
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
LEG GETTONI INTERROGAZIONI
---------- ---------- --------------
17 3
18 2 1
或者直接使用表格版本:
select * from table(p42.num_combo_tab('MRTMRZ'));
LEG GETTONI INTERROGAZIONI
---------- ---------- --------------
17 3
18 2 1
如果您愿意,还可以使用架构级对象和表类型以及架构级函数执行此操作:
create type t_obj as object (leg number, gettoni number, interrogazioni number)
/
create type t_tab is table of t_obj
/
create or replace function num_combo_tab (p_param varchar2)
return t_tab pipelined as
type t_tmp_tab is table of t_obj index by pls_integer;
l_tab t_tmp_tab;
l_leg number;
l_gettoni number;
l_interrogazioni number;
l_cursor sys_refcursor;
begin
l_cursor := num_gettoni(p_param);
loop
fetch l_cursor into l_leg, l_gettoni;
exit when l_cursor%notfound;
l_tab(l_leg) := new t_obj(l_leg, l_gettoni, null);
end loop;
close l_cursor;
l_cursor := num_interrogazioni(p_param);
loop
fetch l_cursor into l_leg, l_interrogazioni;
exit when l_cursor%notfound;
if l_tab.exists(l_leg) then
l_tab(l_leg).interrogazioni := l_interrogazioni;
else
l_tab(l_leg) := new t_obj(l_leg, null, l_interrogazioni);
end if;
end loop;
close l_cursor;
for i in l_tab.first..l_tab.last loop
pipe row (l_tab(i));
end loop;
end num_combo_tab;
/
那么你可以称之为:
select * from table(num_combo_tab('MRTMRZ'));
LEG GETTONI INTERROGAZIONI
---------- ---------- --------------
17 3
18 2 1
但无论如何,在一个包中包含这个函数和您的原始函数可能更明智
显然,在上述所有情况下,尽可能使用您自己的数据类型和
%type
,因为我没有您的表,所以我使用了例如p_param varchar
来代替现有函数声明其参数的方式。不容易。谁或什么人将使用合并的结果?这些函数是独立的还是在一个包中?此过程的唯一任务是调用这些函数以显示结果。现在,这些函数是独立的。如果您更简单,可以假设这些函数在一个包中
select * from table(num_combo_tab('MRTMRZ'));
LEG GETTONI INTERROGAZIONI
---------- ---------- --------------
17 3
18 2 1