Oracle 11g:在过程中使用游标

时间:2012-03-19 12:30:06

标签: sql database oracle plsql

我正在尝试从程序中返回两个ref游标并遇到一些麻烦。我要做的是从第一个光标中获取信息,从中选择一些字段并加入其他信息并将结果粘贴到表变量中...然后从该表中选择不同的项到第二个光标。但我无法编译。有人可以告诉我,我做错了吗?

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;

2 个答案:

答案 0 :(得分:4)

你不能使用这个结构:

for item in c_items loop

带有REF CURSOR。它期望c_items成为标准的PL / SQL CURSOR。这是你得到的错误的直接原因。如果你想循环一个REF CURSOR,据我所知,你需要使用显式的FETCH语句并自己处理循环条件。

此外,你所说的你想做的事情并没有多大意义。如果从过程体内的c_items光标中获取,则将其返回给调用者也是令人困惑的。在您的评论中,您使用短语“select into the cursor”,这意味着您可能会将光标视为可以重复迭代的静态集合。情况并非如此 - 游标表示内存中的活动查询。从光标中获取一行后,无法再次获取该行。

由于我不理解代码的最终目标,因此我不确定该建议是什么。如果你真的需要处理来自c_items的行并将其作为可用的REF CURSOR返回,那么唯一的选择可能是关闭并重新打开它。

答案 1 :(得分:1)

改变这个:

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