2011-11-22 15 views
3

私は、パラメータを(clob型として)クエリを受け取り、返すためにこのクエリの行を '選択'する関数を持っています。クエリのサイズが32kb(〜150kb)を超えているため、dbms_sqlを使用する必要があります。大規模なクエリを実行し、Oracleで行を返す

私は結果にフェッチの時点で立ち往生しています:

-- execute immediate style (does not work with clob): 
EXECUTE IMMEDIATE large_query BULK COLLECT INTO V_TAB ; 

-- dbms_sql style: 
v_upperbound := CEIL(DBMS_LOB.GETLENGTH(large_query)/256); 
FOR i IN 1..v_upperbound 
LOOP 
    v_sql(i) := DBMS_LOB.SUBSTR(large_query,256,((i-1)*256)+1);        
END LOOP; 
v_cur := DBMS_SQL.OPEN_CURSOR; 
DBMS_SQL.PARSE(v_cur, v_sql, 1, v_upperbound, FALSE, DBMS_SQL.NATIVE); 
v_ret := DBMS_SQL.EXECUTE(v_cur); 

-- NOW WHAT?? 

私は、Oracle 9iの/ 10gでので、私はdbms_slq.to_refcursorを使用することはできません。

提案がありますか?

答えて

3

次はOracleのドキュメントの例です。基本的にはdbms_sql.fetch_rowsdbms_sql.column_valueが必要:私は答えに基づいた何ザッツ

CREATE TABLE multi_tab (num NUMBER, 
         dat1 DATE, 
         var VARCHAR2(24), 
         dat2 DATE) 

declare 
    c  NUMBER; 
    d  NUMBER; 
    n_tab DBMS_SQL.NUMBER_TABLE; 
    d_tab1 DBMS_SQL.DATE_TABLE; 
    v_tab DBMS_SQL.VARCHAR2_TABLE; 
    d_tab2 DBMS_SQL.DATE_TABLE; 
    indx NUMBER := 10; 
BEGIN 

    c := DBMS_SQL.OPEN_CURSOR; 
    DBMS_SQL.PARSE(c, 'select * from multi_tab order by 1', DBMS_SQL.NATIVE); 

    DBMS_SQL.DEFINE_ARRAY(c, 1, n_tab, 5, indx); 
    DBMS_SQL.DEFINE_ARRAY(c, 2, d_tab1, 5, indx); 
    DBMS_SQL.DEFINE_ARRAY(c, 3, v_tab, 5, indx); 
    DBMS_SQL.DEFINE_ARRAY(c, 4, d_tab2, 5, indx); 

    d := DBMS_SQL.EXECUTE(c); 

    loop 
    d := DBMS_SQL.FETCH_ROWS(c); 

    DBMS_SQL.COLUMN_VALUE(c, 1, n_tab); 
    DBMS_SQL.COLUMN_VALUE(c, 2, d_tab1); 
    DBMS_SQL.COLUMN_VALUE(c, 3, v_tab); 
    DBMS_SQL.COLUMN_VALUE(c, 4, d_tab2); 

    EXIT WHEN d != 5; 
    END LOOP; 

    DBMS_SQL.CLOSE_CURSOR(c); 
0

-- open cursor and execute the query 
v_cur := DBMS_SQL.OPEN_CURSOR; 
DBMS_SQL.PARSE(v_cur, v_sql, 1, v_upperbound, FALSE, DBMS_SQL.NATIVE); 
v_ret := DBMS_SQL.EXECUTE(v_cur); 

-- define a column to receive the result (in my case, it's a single varchar2 column) 
dbms_sql.define_column(v_cur, 1, V_ROW, 4000); 

-- initialize de result table (TABELA_REGISTROS_TYPE is a table of varchar2(4000)) 
v_tab := TABELA_REGISTROS_TYPE(); 

-- initializa a counter 
v_d := 1; 

-- loop through result rows 
LOOP 

    -- fetch a row into a varchar2(4000) variable 
    EXIT WHEN DBMS_SQL.FETCH_ROWS(v_cur) = 0; 
    DBMS_SQL.COLUMN_VALUE(v_cur, 1, V_ROW); 

    -- append that row into result set 
    V_TAB.EXTEND(); 
    V_TAB(v_d) := v_row; 
    v_d := v_d + 1; 

END LOOP; 

-- finally close the cursor 
DBMS_SQL.close_cursor(v_cur); 

-- then return the result set 
RETURN V_TAB; 
関連する問題