2013-05-30 68 views
2

我有一個程序來生成基於輸入的動態查詢字符串。此查詢可以從我的數據庫中的任何表或連接表中進行選擇,並且列名和列數未知。Oracle:如何從動態查詢中獲取數據?

現在,以這個查詢字符串作爲唯一的輸入,我想從結果中獲取所有數據並逐行輸出,有沒有辦法做到這一點?

~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~我已經解決了這個問題,幫助別人,這是我使用的一段代碼:

 DECLARE 
      v_curid NUMBER; 
      v_desctab DBMS_SQL.DESC_TAB; 
      v_colcnt NUMBER; 
      v_name_var VARCHAR2(10000); 
      v_num_var NUMBER; 
      v_date_var DATE; 
      v_row_num NUMBER; 
      p_sql_stmt VARCHAR2(1000); 
     BEGIN 
      v_curid := DBMS_SQL.OPEN_CURSOR; 
      p_sql_stmt :='SELECT * FROM emp'; 
      DBMS_SQL.PARSE(v_curid, p_sql_stmt, DBMS_SQL.NATIVE); 
      DBMS_SQL.DESCRIBE_COLUMNS(v_curid, v_colcnt, v_desctab); 

      -- Define columns: 
      FOR i IN 1 .. v_colcnt LOOP 
      IF v_desctab(i).col_type = 2 THEN 
       DBMS_SQL.DEFINE_COLUMN(v_curid, i, v_num_var); 
       ELSIF v_desctab(i).col_type = 12 THEN 
       DBMS_SQL.DEFINE_COLUMN(v_curid, i, v_date_var); 
       ELSE 
       DBMS_SQL.DEFINE_COLUMN(v_curid, i, v_name_var, 50); 
       END IF; 
      END LOOP; 
      v_row_num := dbms_sql.execute(v_curid); 
      -- Fetch rows with DBMS_SQL package: 
      WHILE DBMS_SQL.FETCH_ROWS(v_curid) > 0 LOOP 
       FOR i IN 1 .. v_colcnt LOOP 
       IF (v_desctab(i).col_type = 1) THEN 
         DBMS_SQL.COLUMN_VALUE(v_curid, i, v_name_var); 
       ELSIF (v_desctab(i).col_type = 2) THEN 
         DBMS_SQL.COLUMN_VALUE(v_curid, i, v_num_var); 
       ELSIF (v_desctab(i).col_type = 12) THEN 
         DBMS_SQL.COLUMN_VALUE(v_curid, i, v_date_var); 
       END IF; 
      END LOOP; 
      END LOOP; 
      DBMS_SQL.CLOSE_CURSOR(v_curid); 
     END; 
     /
+0

表列可以從f.ex.獲得'dba_tab_columns',構建動態查詢並使用'REF CURSOR'。如果遇到問題,請編輯註釋併發布您的代碼,以便我們盡力幫助您。 – Chorel

回答

3

你可以做到這一點與DBMS_SQL包。

更新 要獲得有關DBMS_SQL的更詳細的參考,請轉到here

0

如果您在PL/SQL中構建您的字符串,您可以使用EXECUTE IMMEDIATE. < - 鏈接運行它。使用BULK COLLECT INTO並輸出集合。

+0

如何通過使用'EXECUTE IMMEDIATE'從想返回多行的查詢中獲取數據? – Chorel

0

<PRE> 
 
DECLARE 
 
    RUN_S   CLOB; 
 
    IGNORE  NUMBER; 
 
    SOURCE_CURSOR NUMBER; 
 
    PWFIELD_COUNT NUMBER DEFAULT 0; 
 
    L_DESCTBL  DBMS_SQL.DESC_TAB2; 
 
    Z_NUMBER  NUMBER; 
 
BEGIN 
 
    RUN_S   := ' SELECT 1  AS VAL1, 
 
          2  AS VAL2, 
 
          CURSOR (SELECT 11 AS VAL11, 
 
              12 AS VAL12 
 
             FROM DUAL) AS CUR1, 
 
          CURSOR (SELECT 11 AS VAL11, 
 
              12 AS VAL12 
 
             FROM DUAL) AS CUR2 
 
         FROM DUAL'; 
 
    SOURCE_CURSOR := DBMS_SQL.OPEN_CURSOR; 
 
    DBMS_SQL.PARSE(SOURCE_CURSOR, RUN_S, DBMS_SQL.NATIVE); 
 
    DBMS_SQL.DESCRIBE_COLUMNS2(SOURCE_CURSOR, PWFIELD_COUNT, L_DESCTBL); -- get record structure 
 
    FOR I IN 1 .. PWFIELD_COUNT LOOP 
 
     DBMS_OUTPUT.PUT_LINE('Col ' || I || ' Type:' || L_DESCTBL(I).COL_TYPE); 
 
     IF L_DESCTBL(I).COL_TYPE = 2 THEN 
 
     DBMS_SQL.DEFINE_COLUMN(SOURCE_CURSOR, I, Z_NUMBER); 
 
     END IF; 
 
     NULL; 
 
    END LOOP; 
 
    IGNORE := DBMS_SQL.EXECUTE(SOURCE_CURSOR); 
 
    LOOP 
 
     IF DBMS_SQL.FETCH_ROWS(SOURCE_CURSOR) > 0 THEN 
 
     FOR I IN 1 .. PWFIELD_COUNT LOOP 
 
      IF L_DESCTBL(I).COL_TYPE IN (2) THEN 
 
       DBMS_SQL.COLUMN_VALUE(SOURCE_CURSOR, I, Z_NUMBER); 
 
       DBMS_OUTPUT.PUT_LINE('Col ' || I || ' Value:' || Z_NUMBER); 
 
      END IF; 
 
     END LOOP; 
 
     ELSE 
 
     EXIT; 
 
     END IF; 
 
    END LOOP; 
 
END; 
 
</PRE>

+0

如何使用CURSOR TYPE COLUMN從SQL中獲取值 – alpertandogan

相關問題