1

我在下面有三个 sql 块。第一个和第二个块工作正常。但第三个只返回一行。在我的真实示例中,我有 13 个 refcursor,每个查询都有几列。我想避免编写数百个 dbms_out.put_line(cur.column_name) 语句

--#1 correctly returns 8 rows.
VAR rc REFCURSOR
BEGIN
OPEN :rc FOR SELECT object_id,object_name from user_objects where rownum < 9;
END;
print rc
--------------------------------------------------------------

--#2 correctly returns 8 rows
set serveroutput on
BEGIN
for cur in (select object_id,object_name from user_objects where rownum < 9)
loop
    dbms_output.put_line(cur.object_id);
    dbms_output.put_line(cur.object_name);
end loop;
END;
---------------------------------------------------------------

--#3 FAIL, only returns 1 row
set serveroutput on
VAR rc REFCURSOR
BEGIN
for cur in (select object_id,object_name from user_objects where rownum < 9)
loop
OPEN :rc FOR SELECT object_id,object_name from user_objects where object_id = cur.object_id;
end loop;
END;
print rc
4

2 回答 2

1

它不是非常漂亮,但你可以这样做:

VAR rc1 REFCURSOR
VAR rc2 REFCURSOR
VAR rc3 REFCURSOR

BEGIN
  for cur in (select object_id,rownum from user_objects where rownum < 4)
  loop
    case cur.rownum
      when 1 then OPEN :rc1 FOR
        SELECT object_id,object_name from user_objects
        where object_id = cur.object_id;
      when 2 then OPEN :rc2 FOR
        SELECT object_id,object_name from user_objects
        where object_id = cur.object_id;
      when 3 then OPEN :rc3 FOR
        SELECT object_id,object_name from user_objects
        where object_id = cur.object_id;
    end case;
  end loop;
END;
/

print rc1
print rc2
print rc3

这很有效,只要您在块运行后打印出多个游标。

如果您在 11g 上,您也许可以通过其过程完成本文建议的操作rc_to_dbms_sql。我不确定这是否完全符合简报,但它至少使dbms_output生成自动化。您可能可以使用dbms_sql而不是 a来做类似的事情sys_refcursor,解析您的内部选择并仍然使用一个过程来自动显示结果。不过,我不确定这对于您的真实案例是否会过大。

于 2013-07-25T18:57:33.477 回答
0
set serveroutput on
VAR rc REFCURSOR
BEGIN
  OPEN :rc FOR SELECT object_id, object_name from user_objects where object_id IN (
     SELECT object_id FROM user_objects WHERE rownum < 9
  );
END;
print rc

cur如果子查询就足够了,我不知道您需要什么。无论如何,游标绑定到一个选择,并且没有简单的方法可以动态附加另一个选择(这是 UNION ALL 静态执行的操作

不要担心性能,引擎(优化器)足够聪明,在这种情况下只执行一次 IN ( SELECT )。

于 2013-07-25T17:09:04.800 回答