2009-09-02 9 views
11

Jak uzyskać dynamiczne wybrane wyniki EXECUTE w języku PL/SQL od Oracle sqlplus?Wyświetl dynamiczne WYKONAJ Wyjście w obrębie pl/sql Od sqlplus

Piszę prosty skrypt SQLPLUS zebrać sumę wszystkich NUMBER kolumn danej tabeli:

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

Dynamicznie generowane SQL, gdy wykonywane, daje coś takiego:

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

jednak nawet z SET SERVEROUTPUT ON, uruchamiając skrypt sQLPLUS daje tylko:

PL/SQL procedure successfully completed. 

Odpowiedz

11

będziesz musiał pobrać wynik z SELECT, aby go wyświetlić. Można użyć synthax EXECUTE IMMEDIATE sql_query INTO var1, var2.. varn. Jednak w twoim przypadku liczba kolumn jest nieznana podczas kompilacji.

Istnieje wiele sposobów można sobie z tym poradzić:

  1. można użyć DBMS_SQL i pętli na kolumnach wyjściu.
  2. można zbudować kolumnę ze wszystkimi wynikami z czytelnym formacie CSV jak XML

będę 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

Dzięki, idealne! Żałuję, że nie mogę cię głosować :) – Jerry

+0

Jerry, teraz możesz (wierzę, że potrzebujesz tylko 15 przedstawicieli na oddanie głosu) –