2009-09-02 17 views
11

Cómo obtener los resultados de selección dinámica de EXECUTE dentro de PL/SQL desde Oracle sqlplus?Mostrar Dynamic EXECUTE Salida dentro de pl/sql De sqlplus

Estoy escribiendo un simple script de sqlplus para recoger la suma de todos los NUMBER columnas de una tabla dada:

SET SERVEROUTPUT ON 

DECLARE 
     CURSOR column_cur IS 
       SELECT column_name FROM ALL_TAB_COLS 
       WHERE owner = '&scheme_name' AND table_name = '&table_name' 
       AND data_type = 'NUMBER'; 
     sql_query VARCHAR2(32767); 
BEGIN 
     sql_query := 'select '; 
     FOR column_rec IN column_cur LOOP 
       sql_query := sql_query || 'SUM(' || column_rec.column_name || 
         ') "SUM(' || column_rec.column_name || ')", '; 

     END LOOP; 
     sql_query := substr(sql_query, 0, length(sql_query)-2) || -- remove trailing ', ' 
       ' from &scheme_name' || '.&table_name'; 
     EXECUTE IMMEDIATE sql_query; 
END; 
/

La sentencia SQL generada dinámicamente, cuando se ejecuta, da algo así como:

SUM(X) | SUM(Y) | SUM(Z) | 
-------------------------- 
111 | 222 | 333 | 

Sin embargo, incluso con SET SERVEROUTPUT ON, la ejecución del script sqlplus da solamente:

PL/SQL procedure successfully completed. 

Respuesta

11

tendrá que recuperar el resultado de su SELECCIÓN para mostrarlo. Utilizaría el synthax EXECUTE IMMEDIATE sql_query INTO var1, var2.. varn. Sin embargo, en su caso, el número de columnas se desconoce en el momento de la compilación.

Hay un número de maneras en que podría hacer frente a esto:

  1. podría utilizar DBMS_SQL y bucle en las columnas de la salida.
  2. se podría construir una columna con todos los resultados con un formato legible como CSV de XML

voy a Demo 1:

SQL> DEFINE scheme_name=SYS 
SQL> DEFINE table_name=ALL_OBJECTS 
SQL> DECLARE 
    2  sql_query VARCHAR2(32767); 
    3  l_cursor NUMBER := dbms_sql.open_cursor; 
    4  l_dummy NUMBER; 
    5  l_columns dbms_sql.desc_tab; 
    6  l_value NUMBER; 
    7 BEGIN 
    8  sql_query := 'select '; 
    9  FOR column_rec IN (SELECT column_name 
10       FROM ALL_TAB_COLS 
11       WHERE owner = '&scheme_name' 
12       AND table_name = '&table_name' 
13       AND data_type = 'NUMBER') LOOP 
14  sql_query := sql_query || 'SUM(' || column_rec.column_name 
15      || ') "SUM(' || column_rec.column_name || ')", '; 
16  END LOOP; 
17  sql_query := substr(sql_query, 0, length(sql_query) - 2) 
18     || ' from &scheme_name' || '.&table_name'; 
19  dbms_sql.parse(l_cursor, sql_query, dbms_sql.NATIVE); 
20  dbms_sql.describe_columns(l_cursor, l_dummy, l_columns); 
21  FOR i IN 1..l_columns.count LOOP 
22  dbms_sql.define_column(l_cursor, i, l_columns(i).col_type); 
23  END LOOP; 
24  l_dummy := dbms_sql.execute_and_fetch(l_cursor, TRUE); 
25  FOR i IN 1..l_columns.count LOOP 
26  dbms_sql.column_value(l_cursor, i, l_value); 
27  dbms_output.put_line(l_columns(i).col_name ||' = '||l_value); 
28  END LOOP; 
29 END; 
30/

SUM(DATA_OBJECT_ID) = 260692975 
SUM(OBJECT_ID) = 15242783244 
+0

Gracias, perfecto! Desearía poder votar por ti :) – Jerry

+0

Jerry, ahora puedes (creo que solo necesitas 15 representantes para votar) –

Cuestiones relacionadas