将REF CURSOR复制到临时表

时间:2014-10-20 22:18:16

标签: oracle database-connection

是否有快速方法将REF CURSOR刷新到oracle中的临时表中
CURSOR尺寸在5K到100K行之间变化
目前我正在使用for循环,但它非常慢
无法更改SOME_FUNCTION_CALL函数的OUT参数。

DECLARE
v_return SYS_REFCURSOR;
VAR_A varchar2(100);
VAR_B varchar2(100);

BEGIN 
 v_return := SOME_FUNCTION_CALL();
LOOP
FETCH v_return into VAR_A,VAR_B
EXIT WHEN v_return%NOTFOUND
          INSERT INTO temp_table(a,b) values (VAR_A,VAR_B);
END LOOP;
CLOSE v_return;
END LOOP;

1 个答案:

答案 0 :(得分:2)

可能不是。

通过对本地集合执行BULK COLLECT而不是逐行提取,可以使代码更有效。像

这样的东西
DECLARE 
  TYPE vc100_tbl IS TABLE OF VARCHAR2(100);

  l_return    SYS_REFCURSOR;
  l_var_a_tbl vc100_tbl;
  l_var_b_tbl vc100_tbl;
BEGIN
  l_return := some_function_call();

  LOOP
    FETCH l_return
     BULK COLLECT INTO l_var_a_tbl, l_var_b_tbl
    LIMIT 100;

    EXIT WHEN l_var_a_tbl.count = 0;

    FORALL i IN 1 .. l_var_a_tbl.count
      INSERT INTO temp_table( a, b )
        VALUES( l_var_a_tbl(i), l_var_b_tbl(i) );
  END LOOP;

  close l_return;
END;

这将减少SQL和PL / SQL引擎之间发生的上下文转换次数。但是根据你对#34;非常慢的定义,上下文转换似乎不太可能是你最紧迫的问题。如果我猜测,如果你的代码是非常缓慢的话,那我就会下注"对于该术语的大多数定义,问题可能是用于在some_function中打开游标的查询速度很慢,而且大部分时间都花在执行该查询上以生成您的行想要取。如果是这种情况,您需要优化查询。

在架构上,这种方法似乎也存在问题。即使您无法更改函数的定义,也无法分解函数正在执行的查询,以便您可以在不调用函数的情况下使用相同的代码?例如,您是否可以将函数调用的查询分解为视图,然后从代码中调用该视图?