2009-09-02 8 views
11

Wie erhalten Sie die dynamische Auswahl Ergebnisse von EXECUTE in PL/SQL von Oracle sqlplus?Anzeige Dynamische EXECUTE Ausgabe innerhalb pl/sql Von sqlplus

Ich bin ein einfaches sqlplus Skript zu schreiben, die Summe aller NUMBER Spalten einer bestimmten Tabelle zu sammeln:

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

Die dynamisch generierten SQL-Anweisung, wenn sie ausgeführt werden, gibt so etwas wie:

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

aber auch bei SET SERVEROUTPUT ON, gibt das sqlplus Skript ausgeführt nur:

PL/SQL procedure successfully completed. 

Antwort

11

Sie müssen das Ergebnis von Ihrem SELECT abrufen, um es anzuzeigen. Sie würden den Synthax EXECUTE IMMEDIATE sql_query INTO var1, var2.. varn verwenden. In Ihrem Fall ist die Anzahl der Spalten zur Kompilierzeit unbekannt.

Es gibt eine Reihe von Möglichkeiten, wie Sie damit umgehen könnten:

  1. Sie DBMS_SQL und Schleife auf den Spalten der Ausgabe verwenden könnten.
  2. Sie könnten eine Spalte mit allen Ergebnissen mit einem lesbaren Format wie CSV von

XML bauen I 1 Demo:

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

Dank, perfekt! Ich wünschte, ich könnte dich wählen :) – Jerry

+0

Jerry, jetzt kannst du (ich glaube, du brauchst nur 15 Wiederholungen, um zu stimmen) –