Oracle 11g:在过程中使用游标
Posted
技术标签:
【中文标题】Oracle 11g:在过程中使用游标【英文标题】:Oracle 11g: Using cursors inside a procedure 【发布时间】:2012-03-19 12:30:06 【问题描述】:我试图从一个过程中返回两个引用游标并且遇到了一些麻烦。我要做的是从第一个光标中获取信息,从中选择一些字段并加入其他一些信息并将结果粘贴到表变量中......然后从该表中选择不同的项目到第二个光标。但我无法编译它。有人可以告诉我我做错了什么吗?
type T_CURSOR is REF CURSOR
procedure FetchSL3Details_PRC
(
c_items out T_CURSOR,
c_identifiers out T_CURSOR,
p_niin in char
) as
v_idents IDENTIFIER_TABLE_TYPE:= IDENTIFIER_TABLE_TYPE();
BEGIN
open c_items for
select
its.item_set_id,
its.niin,
its.parent_niin,
its.commodity_id,
its.service_type,
its.sl3_type,
its.qty,
its.created_id,
its.created_dt,
its.modified_id,
its.modified_dt
from
item_set its
start with its.niin = p_niin
connect by prior its.niin = its.parent_niin;
for item in c_items loop
v_idents.extend;
v_idents(v_idents.LAST) := identifier_row_type(item.commodity_id,
get_group_name_fun(item.commodity_id),
0);
v_idents.extend;
v_idents(v_idents.LAST) := identifier_row_type(item.created_id,
get_formatted_name_fun(item.created_id),
0);
v_idents.extend;
v_idents(v_idents.LAST) := identifier_row_type(item.modified_id,
get_formatted_name_fun(item.modified_id),
0);
end loop;
open c_identifiers for
select
distinct(v.id),
v.name,
v.type
from
v_idents v;
END FetchSL3Details_PRC;
【问题讨论】:
什么是 T_CURSOR?我一般使用 sys_refcursor 作为保持打开游标的变量类型。 T_CURSOR 是引用光标的 typedef... for 循环开头的错误是 (506,19) “C_ITEMS 不是过程或未定义”。我可以选择光标,但我不能为 for 循环重新打开它。它还抱怨 v_idents 表不存在... 【参考方案1】:你不能使用这个结构:
for item in c_items loop
带有 REF CURSOR。它期望 c_items
是标准的 PL/SQL CURSOR
。这是您遇到错误的直接原因。如果你想循环一个 REF CURSOR,据我所知,你需要使用显式的 FETCH 语句并自己处理循环条件。
此外,你所说的你正在尝试做的事情并不完全合理。如果您从过程主体内的c_items
游标中获取,将其返回给调用者也会令人困惑。在您的评论中,您使用了“选择进入光标”这一短语,这意味着您可能将光标视为可以反复迭代的静态集合。情况并非如此——游标代表内存中的活动查询。一旦从游标中取出一行,就不能再取出了。
由于我不了解代码的最终目标,因此我不确定该建议什么。如果您确实需要同时处理来自 c_items
的行并将其作为可用的 REF CURSOR 返回,那么唯一的选择可能是关闭并重新打开它。
【讨论】:
【参考方案2】:改变这个:
open c_identifiers for
select
distinct(v.id),
v.name,
v.type
from
v_idents v;
到:
open c_identifiers for
select
distinct(v.id),
v.name,
v.type
from
TABLE(v_idents) v; -- Use TABLE
【讨论】:
谢谢,修复了临时表部分......仍然存在无法从循环的 c_items 游标中提取项目的问题,因此我什至可以填充该表。以上是关于Oracle 11g:在过程中使用游标的主要内容,如果未能解决你的问题,请参考以下文章