set serveroutput on declare l_cur SYS_REFCURSOR ; PROCEDURE CursorOutput( p_refcursor IN OUT SYS_REFCURSOR ) AS l_desc DBMS_SQL.DESC_TAB ; l_cols BINARY_INTEGER ; l_cursor BINARY_INTEGER ; v_varchar2 VARCHAR2( 4000 ) ; v_number NUMBER ; v_date DATE ; l_data varchar2( 32767 ) ; l_columnValue VARCHAR2( 32767 ) ; l_processedRows Number := 0; BEGIN /* Convert refcursor "parameter" to DBMS_SQL cursor... */ l_cursor := DBMS_SQL.TO_CURSOR_NUMBER( p_refcursor ); /* Describe the cursor... */ DBMS_SQL.DESCRIBE_COLUMNS( l_cursor, l_cols, l_desc ); /* Define columns to be fetched. We're only using V2, NUM, DATE for example... for a complete list of the col_types this link is accessible. http://download.oracle.com/docs/cd/B10501_01/server.920/a96540/sql_elements2a.htm#45504 http://forums.oracle.com/forums/thread.jspa?threadID=912475 if not a usable type, will throw new exception */ FOR i IN 1 .. l_cols LOOP IF l_desc(i).col_type = 2 THEN DBMS_SQL.DEFINE_COLUMN(l_cursor, i, v_number); ELSIF l_desc(i).col_type = 12 THEN DBMS_SQL.DEFINE_COLUMN(l_cursor, i, v_date); ELSif l_desc(i).col_type = 01 or l_desc(i).col_type = 96 then DBMS_SQL.DEFINE_COLUMN(l_cursor, i, v_varchar2, 4000); else --raise an exception if the user's query contains a datatype not (yet) supported by this procedure RAISE_APPLICATION_ERROR(-20000, 'Invalid Data Type for conversion to delimited file. {' || l_desc(i).col_name || '}'); END IF; END LOOP; /* -- print out the column names if desired FOR i IN 1 .. l_cols LOOP dbms_output.put_line('** ' || l_desc(i).col_name) ; END LOOP; */ /* Fetch all data... */ WHILE DBMS_SQL.FETCH_ROWS(l_cursor) > 0 LOOP dbms_output.put_line('LINE: ' || l_processedRows || ''); FOR i IN 1 .. l_cols LOOP if l_desc(i).col_type = 12 THEN --we are in a date DBMS_SQL.COLUMN_VALUE(l_cursor, i, v_date); v_varchar2 := to_char(v_date , 'dd-MON-yyyy' ) ; elsif l_desc(i).col_type = 2 THEN --we are in a number DBMS_SQL.COLUMN_VALUE(l_cursor, i, v_number); v_varchar2 := to_char(v_number) ; else --treat it as a string (should be varchar2,char,etc) DBMS_SQL.COLUMN_VALUE(l_cursor, i, v_varchar2); IF v_varchar2 IS NOT NULL THEN v_varchar2 := '"' || v_varchar2 || '"' ; ELSE v_varchar2 := ''; END IF ; end if ; dbms_output.put_line(l_desc(i).col_name || '=>' || v_varchar2) ; END LOOP; l_processedRows := l_processedRows + 1 ; END LOOP; dbms_sql.close_cursor(l_cursor); dbms_output.put_line('I found and processed ' || l_processedRows || ' rows .'); END; begin open l_cur for select * from temp; CursorOutput(p_refcursor => l_cur) ; end ; /
set serveroutput ondeclare l_cur SYS_REFCURSOR ;
PROCEDURE CursorOutput( p_refcursor IN OUT SYS_REFCURSOR ) AS l_desc DBMS_SQL.DESC_TAB ; l_cols BINARY_INTEGER ; l_cursor BINARY_INTEGER ; v_varchar2 VARCHAR2( 4000 ) ; v_number NUMBER ; v_date DATE ; l_data varchar2( 32767 ) ; l_columnValue VARCHAR2( 32767 ) ; l_processedRows Number := 0; BEGIN
/* Convert refcursor "parameter" to DBMS_SQL cursor... */ l_cursor := DBMS_SQL.TO_CURSOR_NUMBER( p_refcursor ); /* Describe the cursor... */ DBMS_SQL.DESCRIBE_COLUMNS( l_cursor, l_cols, l_desc );
/* Define columns to be fetched. We're only using V2, NUM, DATE for example... for a complete list of the col_types this link is accessible. http://download.oracle.com/docs/cd/B10501_01/server.920/a96540/sql_elements2a.htm#45504 http://forums.oracle.com/forums/thread.jspa?threadID=912475 if not a usable type, will throw new exception */ FOR i IN 1 .. l_cols LOOP IF l_desc(i).col_type = 2 THEN DBMS_SQL.DEFINE_COLUMN(l_cursor, i, v_number); ELSIF l_desc(i).col_type = 12 THEN DBMS_SQL.DEFINE_COLUMN(l_cursor, i, v_date); ELSif l_desc(i).col_type = 01 or l_desc(i).col_type = 96 then DBMS_SQL.DEFINE_COLUMN(l_cursor, i, v_varchar2, 4000); else --raise an exception if the user's query contains a datatype not (yet) supported by this procedure RAISE_APPLICATION_ERROR(-20000, 'Invalid Data Type for conversion to delimited file. {' || l_desc(i).col_name || '}'); END IF; END LOOP;
/* -- print out the column names if desired FOR i IN 1 .. l_cols LOOP dbms_output.put_line('** ' || l_desc(i).col_name) ; END LOOP; */
/* Fetch all data... */ WHILE DBMS_SQL.FETCH_ROWS(l_cursor) > 0 LOOP dbms_output.put_line('LINE: ' || l_processedRows || ''); FOR i IN 1 .. l_cols LOOP if l_desc(i).col_type = 12 THEN --we are in a date DBMS_SQL.COLUMN_VALUE(l_cursor, i, v_date); v_varchar2 := to_char(v_date , 'dd-MON-yyyy' ) ; elsif l_desc(i).col_type = 2 THEN --we are in a number DBMS_SQL.COLUMN_VALUE(l_cursor, i, v_number); v_varchar2 := to_char(v_number) ; else --treat it as a string (should be varchar2,char,etc) DBMS_SQL.COLUMN_VALUE(l_cursor, i, v_varchar2); IF v_varchar2 IS NOT NULL THEN v_varchar2 := '"' || v_varchar2 || '"' ; ELSE v_varchar2 := ''; END IF ; end if ; dbms_output.put_line(l_desc(i).col_name || '=>' || v_varchar2) ; END LOOP; l_processedRows := l_processedRows + 1 ; END LOOP;
dbms_sql.close_cursor(l_cursor); dbms_output.put_line('I found and processed ' || l_processedRows || ' rows .');
END;begin open l_cur for select * from temp; CursorOutput(p_refcursor => l_cur) ;end ;/