我下面有三个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
答案 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)。