我有一个存储过程GetRegions
,它将一些列提取到游标中,如下所示:
OPEN out_cur FOR
SELECT id, name, ...
FROM regions, ...
WHERE ...
这个SP在整个地方使用 - 在将返回数十个区域的地方以及将返回数万个地方的地方。
我还有一个函数GetRegionPath
,它可以获取某个区域的“路径”。这是一个中等昂贵的功能 - 在几十个地区运行它没有问题,但数万个是不可接受的。
我需要编写一个存储过程GetRegionsWithPaths
,它可以获得完全相同逻辑的区域,现在和永远为GetRegions
,但其中包含的路径为结果集中的区域。
目前,GetRegionsWithPaths
是GetRegions
的精确副本,并添加了路径:
OPEN out_cur FOR
SELECT id, name, ..., GetRegionPath(id) path
FROM regions, ...
WHERE ...
但这是不可接受的 - 如果有人编辑GetRegions
,则两个SP将不同步。我想要的是从GetRegions
取光标然后添加它的路径。类似的东西:
GetRegions(..., v_cur);
OPEN out_cur FOR
SELECT id, name, ..., GetRegionPath(id) path
FROM ( SELECT * FROM v_cur );
这可能吗?如果是这样,语法是什么?
答案 0 :(得分:1)
一种可能的解决方案(最终可以简化)是使用表函数来处理游标并添加函数值。
假设返回sys_refcursor的函数被称为get_cur
,并且游标由列ID, NAME
组成(这很重要,因为表函数需要类型定义)。
您声明行的TYPE(包括附加路径列)和结果表。
create type t_row is object
( id number(10),
name varchar2(10),
path varchar2(10)
);
/
create type t_rows is table of t_row;
/
并定义表函数获取光标并添加函数调用。
create or replace function get_cur2 return
t_rows
PIPELINED
as
cv_out sys_refcursor;
id number;
name varchar2(100);
begin
cv_out := get_cur;
loop
FETCH cv_out INTO id, name;
exit when cv_out%NOTFOUND;
pipe row(t_row(id,name, GetRegionPath(id)));
end loop;
close cv_out;
return;
end;
/
现在您可以从表格函数中选择数据
select * from table(get_cur2);
ID NAME PATH
---------- ---------- ----------
1 one path 1
2 two path 2
当然您可以使用此查询在第三个函数中打开游标,该函数将返回带有附加路径列的SYS_REFCURSOR。
答案 1 :(得分:1)
使用评论中建议的参数进行替代实施。
假设原始函数看起来像这样
create or replace function get_cur return SYS_REFCURSOR is
cv_out sys_refcursor;
begin
OPEN cv_out
FOR
select Id, name from tab;
return cv_out;
end;
/
您添加一个参数return_path
,该参数为0 - 返回原始光标或1 - 这将返回带有路径列的原始curosr。
实施可能就像这样
create or replace function get_cur_with_param(return_path NUMBER) return SYS_REFCURSOR is
cv_out sys_refcursor;
v_stmt_str VARCHAR2(4000);
begin
v_stmt_str := 'select Id, name '||case when return_path = 1 then ', GetRegionPath(id)' end ||' from tab';
OPEN cv_out FOR v_stmt_str;
return cv_out;
end;
/
比get_cur_with_param(0)
返回2列游标,get_cur_with_param(1)
返回添加了path
列的游标。
请注意,SQL是动态构建的,但只会以两个变体结束,因此解析时没问题。如果查询中有其他参数,请使用绑定变量添加USING子句。