2012-01-03 53 views
5

¿Cómo puedo imprimir todos los campos de una variable de registro en PL/SQL. La variable de registro tiene muchos campos, ¿hay alguna manera mejor que imprimir cada campo? También intentó sql dinámico pero no ayudó.Imprimir campos de registro en PL/SQL

+0

¿Está tratando de imprimir los nombres de los campos de la base de datos o los valores? – DOK

+1

Estoy tratando de imprimir el Nombre del campo y su valor correspondiente. – Iban

+0

Creo que lo que quiere es usar un [cursor] (http://docs.oracle.com/cd/B14117_01/appdev.101/b10807/06_ora.htm#i36655). Estoy con DOK ... ¿desea imprimir todos los campos en un solo registro sin imprimir cada campo? Una redacción más precisa de la pregunta podría ayudar. – Dallas

Respuesta

0

Si se trata de un bloque PL/SQL que está ejecutando en un IDE, entonces podría usar una pizca DBMS_OUTPUT para generar los valores.

http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_output.htm

Por ejemplo:

SET SERVEROUTPUT ON 

DECLARE 
    -- Define the record 
    TYPE test_rectype IS RECORD (
     field1 NUMBER, 
     field2 VARCHAR2 
    ); 
    -- Define a variable for the record 
    test_rec TEST_RECTYPE; 
BEGIN 
    -- Populate the record 
    test_rec.field1 := 1; 
    test_rec.field2 := 'my value'; 
    -- Enable the DBMS_OUTPUT 
    DBMS_OUTPUT.enable(1000000); 
    -- Send the output to the buffer 
    DBMS_OUTPUT.put_line('Field1: '||test_rec.field1||', Field2: '||test_rec.field2); 
END; 

No hay más que DBMS_OUTPUT para echar un vistazo a los documentos desde el enlace anterior.

O bien, puede escribir los valores en un archivo usando UTL_FILE.

http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/u_file.htm

creo que sirve ...

+1

La variable de registro que estoy usando tiene más de 50 campos. Entonces, ¿hay una mejor manera que utilizar DBMS_OUTPUT.PUT_LINE para todos los 50 campos? – Iban

6

Sobre la utilización de ollies DBMS_OUTPUT, pero para ir de forma dinámica a través del cursor

Configuración para las pruebas

/*create table temp (aa varchar2(50) , bb number , cc date) ; 

insert into temp (aa,bb,cc) 
    select chr(level+100) , level, sysdate+level 
    from dual 
    connect by level < 15 ; 
/
*/ 

Bloque para mostrar la prueba (esto supone 11g)

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

le dará este resultado

LINE: 0 
AA=>"e" 
BB=>1 
CC=>04-JAN-2012 
LINE: 1 
AA=>"f" 
BB=>2 
CC=>05-JAN-2012 
LINE: 2 
AA=>"g" 
BB=>3 
CC=>06-JAN-2012 
LINE: 3 
AA=>"h" 
BB=>4 
CC=>07-JAN-2012 
LINE: 4 
AA=>"i" 
BB=>5 
CC=>08-JAN-2012 
LINE: 5 
AA=>"j" 
BB=>6 
CC=>09-JAN-2012 
LINE: 6 
AA=>"k" 
BB=>7 
CC=>10-JAN-2012 
LINE: 7 
AA=>"l" 
BB=>8 
CC=>11-JAN-2012 
LINE: 8 
AA=>"m" 
BB=>9 
CC=>12-JAN-2012 
LINE: 9 
AA=>"n" 
BB=>10 
CC=>13-JAN-2012 
LINE: 10 
AA=>"o" 
BB=>11 
CC=>14-JAN-2012 
LINE: 11 
AA=>"p" 
BB=>12 
CC=>15-JAN-2012 
LINE: 12 
AA=>"q" 
BB=>13 
CC=>16-JAN-2012 
LINE: 13 
AA=>"r" 
BB=>14 
CC=>17-JAN-2012 
I found and processed 14 rows . 

que había hecho algo similar a esto para crear dinámicamente un archivo csv utilización de estos dos enlaces como fuentes http://www.oracle-developer.net/display.php?id=505 http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:88212348059

Dependiendo en lo que está buscando, sin embargo, es posible que desee ejecutarlo en SQL Developer (o Toad) y exportar el r esults!

+0

¡Esto realmente ayuda! Sin embargo, la única entrada que tengo es una variable de registro. No podría consultar en ninguna de las tablas para formar un cursor. Pero sé la tabla en la que se basa este registro, ya que se declara utilizando ROWTYPE. Así que tengo solo un registro (fila) con muchos campos para imprimir. – Iban

+0

@Iban, perdí esa parte, permítanme investigar para ver si eso es posible y, si es así, ¡cuánto lo siento! – Harrison

+0

¡Gracias de antemano! Yo también lo intenté usando SQL dinámico. Puedo obtener los nombres de campo al consultar dba_tab_columns, ya que conozco la tabla en la que se basa el registro. Sin embargo, el registro está fuera del alcance en el bloque SQL dinámico, por lo que se está extrayendo el error. – Iban

Cuestiones relacionadas