loop within fields

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 ;/

原文地址:https://www.cnblogs.com/kakaisgood/p/12706580.html