2009-09-02 27 views
11

Làm thế nào để có được kết quả lựa chọn động của EXECUTE trong PL/SQL từ Oracle sqlplus?Hiển thị đầu ra động EXECUTE Trong phạm vi pl/sql Từ sqlplus

Tôi đang viết một kịch bản sqlplus đơn giản để thu thập tổng của tất cả NUMBER cột của một bảng được đưa ra:

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

Các động tạo ra câu lệnh SQL, khi thực hiện, cung cấp cho một cái gì đó như:

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

Tuy nhiên, ngay cả với SET SERVEROUTPUT ON, chạy tập lệnh sqlplus chỉ cho phép:

PL/SQL procedure successfully completed. 

Trả lời

11

bạn sẽ cần truy xuất kết quả từ SELECT của mình để hiển thị nó. Bạn sẽ sử dụng synthax EXECUTE IMMEDIATE sql_query INTO var1, var2.. varn. Tuy nhiên trong trường hợp của bạn, số cột không xác định tại thời gian biên dịch.

Có một số cách bạn có thể đối phó với điều này:

  1. bạn có thể sử dụng DBMS_SQL và vòng lặp trên các cột của đầu ra.
  2. bạn có thể xây dựng một cột với tất cả các kết quả với một định dạng có thể đọc được như CSV của XML

tôi sẽ giới thiệu 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

Cảm ơn, hoàn hảo! Tôi ước tôi có thể bầu bạn lên :) – Jerry

+0

Jerry, bây giờ bạn có thể (Tôi tin rằng bạn chỉ cần 15 đại diện để bỏ phiếu) –

Các vấn đề liên quan