【问题标题】:Executing large query and returning rows in Oracle在 Oracle 中执行大型查询并返回行
【发布时间】:2011-11-22 21:57:26
【问题描述】:

我有一个函数,它接收一个查询作为参数(作为 clob 类型)并“选择”这个查询的行以返回。我需要使用dbms_sql,因为查询的大小大于 32kb (~150kb)。

我被困在获取结果的地方:

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

有什么建议吗?

【问题讨论】:

    标签: sql oracle plsql cursor


    【解决方案1】:

    这是 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);
    

    【讨论】:

      【解决方案2】:

      这就是我根据答案所做的:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-12
        • 1970-01-01
        • 1970-01-01
        • 2022-01-22
        • 2017-09-10
        • 2015-10-20
        相关资源
        最近更新 更多