Skip to Main Content
  • Questions
  • How do i see the contents of the refcursor (If I dont know the no of columns it is returning)

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Koshal.

Asked: October 31, 2006 - 12:15 pm UTC

Last updated: April 09, 2008 - 2:03 pm UTC

Version: 9.2.0.7

Viewed 10K+ times! This question is

You Asked

How do i see the contents of the refcursor (If I dont know the no of columns it is returning) pl/sql

Thanks
Koshal


and Tom said...

you cannot, in plsql you either know it AT COMPILE TIME, or you do not know it.

Other languages like pro*c, OCI, jdbc, VB - they can get a cursor and describe it. To do dynamic sql in plsql (currently, 10gr2 and before) you must use DBMS_SQL if you do not know the

a) number of output columns
b) datatype of output columns

at compile time. DBMS_SQL provides an API to let you "describe" the cursor, REF CURSORS (in plsql) do not.

Rating

  (5 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

nice-to-have

djb, November 01, 2006 - 10:38 am UTC

It would seem this feature (describe for a ref-cursor in PL/SQL) would be highly useful. I've seen requests for it quite often; not only on your site, but others as well.

Do you have any idea if they might be incorporating it in a [near] future version?


Tom Kyte
November 01, 2006 - 11:18 am UTC

yes, it will, I've already seen it ;)

what about strongly typed rc?

A reader, November 01, 2006 - 10:40 am UTC

But strongly typed ref cursors can do that right (ie. describe the cursor)?

Tom Kyte
November 01, 2006 - 11:19 am UTC

there is no need to describe a strongly typed ref cursor.

by definition, you know what it looks like when you compiled it.

If you only want to see the contents for debugging purposes...

Mobra, November 01, 2006 - 11:22 am UTC

... you can use the following procedure:



procedure print (p_refcursor in sys_refcursor,
p_null_handling in number := 0)
as
l_xml xmltype;
l_context dbms_xmlgen.ctxhandle;
l_clob clob;

l_null_self_argument_exc exception;
pragma exception_init (l_null_self_argument_exc, -30625);

procedure print (p_msg in varchar2)
as
l_text varchar2(32000) := p_msg;
begin

loop
exit when l_text is null;
dbms_output.put_line(substr(l_text,1,250));
l_text:=substr(l_text, 251);
end loop;

end print;

begin

/*

Purpose: print debug information (ref cursor)

Remarks: outputs weakly typed cursor as XML

*/

-- get a handle on the ref cursor
l_context:=dbms_xmlgen.newcontext (p_refcursor);

/*

# DROP_NULLS CONSTANT NUMBER:= 0; (Default) Leaves out the tag for NULL elements.
# NULL_ATTR CONSTANT NUMBER:= 1; Sets xsi:nil="true".
# EMPTY_TAG CONSTANT NUMBER:= 2; Sets, for example, <foo/>.

*/

-- how to handle null values
dbms_xmlgen.setnullhandling (l_context, p_null_handling);

-- create XML from ref cursor
l_xml:=dbms_xmlgen.getxmltype (l_context, dbms_xmlgen.none);

print('Number of rows in ref cursor: ' || dbms_xmlgen.getnumrowsprocessed (l_context));

begin
l_clob:=l_xml.getclobval();
print('Size of XML document (anything over 32K will be truncated): ' || length(l_clob));
print(substr(l_clob,1,32000));
exception
when l_null_self_argument_exc then
print('Empty dataset.');
end;

end print;


Tom Kyte
November 01, 2006 - 6:13 pm UTC

indeed, much like this:

</code> http://asktom.oracle.com/Misc/i-like-online-communities.html <code>

thanks!

when you need it for debug

Michal Pravda, April 08, 2008 - 4:59 am UTC

then you can use this approach.
However, it fails if the resulting string is longer than 32K.

declare
cur sys_refcursor;

procedure p(p_str in varchar2) is
l_str long := p_str || chr(10);
l_piece long;
n number;
begin
loop
exit when l_str is null;
n := instr(l_str, chr(10));
l_piece := substr(l_str, 1, n - 1);
l_str := substr(l_str, n + 1);
loop
exit when l_piece is null;
dbms_output.put_line(substr(l_piece, 1, 250));
l_piece := substr(l_piece, 251);
end loop;
end loop;
end;

function print_refcursor(cur sys_refcursor) return varchar2 as
begin
return xmltype(cur) .getstringval();
end print_refcursor;

begin
open cur for
select * from all_objects where rownum < 3;

p(print_refcursor(cur));
end;
/

Tom Kyte
April 09, 2008 - 2:03 pm UTC

so, use a clob

See contents of SYS_REFCURSOR using XML and clob

Vinod, May 21, 2009 - 4:09 pm UTC

I am only pasting the code snippet after creating the sql string...

--In the declare section
out_result_cur SYS_REFCURSOR;
out_query_result CLOB;
qryCtx DBMS_XMLGEN.ctxHandle;

--In the executable section
OPEN out_result_cur FOR v_select_sql;

qryCtx := dbms_xmlgen.newCOntext(out_result_cur);
out_query_result := dbms_xmlgen.getXml(qryCtx);
dbms_xmlgen.closeContext(qryCtx);

print_clob(out_query_result);


PROCEDURE print_clob( p_clob IN CLOB )
IS
l_offset NUMBER DEFAULT 1;
BEGIN
LOOP
EXIT WHEN l_offset > DBMS_LOB.GETLENGTH(p_clob);
DBMS_OUTPUT.PUT_LINE( DBMS_LOB.SUBSTR( p_clob, 255, l_offset ) );
l_offset := l_offset + 255;
END LOOP;
END;


More to Explore

DBMS_SQL

More on PL/SQL routine DBMS_SQL here