2009-09-02 30 views
11

如何從Oracle sqlplus獲得PL/SQL中EXECUTE的動態選擇結果?在pl/sql中顯示動態EXECUTE輸出從sqlplus

我正在寫一個簡單的sqlplus腳本來收集給定表的所有NUMBER列的總和:

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

動態生成的SQL語句執行時,給出了這樣的:

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

但是,即使使用SET SERVEROUTPUT ON,運行sqlplus腳本也只給出:

PL/SQL procedure successfully completed. 

回答

11

您需要從SELECT中檢索結果才能顯示結果。你會使用合成器EXECUTE IMMEDIATE sql_query INTO var1, var2.. varn。但是在你的情況下,列的數量在編譯時是未知的。

有很多的,你可以解決這個問題的方法:

  1. ,你可以在輸出的列使用DBMS_SQL和循環。
  2. ,你可以與所有使用XML

像CSV以可讀格式結果建立一個專欄中,我將展示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

謝謝,完美!我希望我可以投你:) – Jerry 2009-09-02 09:52:04

+0

傑裏,現在你可以(我相信你只需要15代表投票) – 2009-09-02 11:29:22