如何在不使用dbms_output.put_line的情况下输出pl / sql动态选择中的所有行

时间:2013-07-25 16:55:29

标签: oracle oracle10g sqlplus

我下面有三个sql块。第一和第二块工作正常。但第三只返回一行。在我的真实世界示例中,我有13个refcursors,每个查询都有几列。我想避免编写数百个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

2 个答案:

答案 0 :(得分: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程序完成了this article建议的操作。我不确定这是否会完全符合要求,但它至少会自动化dbms_output代。您可以使用dbms_sql而不是sys_refcursor执行类似的操作,解析内部选择并仍使用过程自动显示结果。我不确定你的真实案例是否会有点过分。

答案 1 :(得分: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)。