EXECUTE IMMEDIATE中的BULK COLLECT LIMIT

时间:2015-11-15 09:57:16

标签: oracle plsql oracle10g

是否可以使用execute immediate在批量收集中设置限制?

我有下面的脚本,但是在使用LIMIT时遇到错误。

declare
v_query varchar2(3000); 
begin 

v_query := 'select 1 from dual' -- this is just a sample query. 

execute immediate  v_query 
bulk collect into table1 --table type

end;

如果我的代码无法限制,是否有任何解决方法?

谢谢!

2 个答案:

答案 0 :(得分:4)

似乎EXECUTE IMMEDIATE语法不允许批量收集子句中的LIMIT

http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/executeimmediate_statement.htm#CJACGJJG

enter image description here
bulk_collect_into_clause
http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/returninginto_clause.htm#CJAIAGHJ enter image description here

您可以使用游标和FETCH .. LIMIT命令以及OPEN..FOR命令,以这种方式:

DECLARE
  ....
  cur sys_refcursor;
BEGIN
  v_query := 'SELECT level AS x FROM dual CONNECT BY LEVEL <=10';
  OPEN cur FOR v_query;
  LOOP
     FETCH cur BULK COLLECT INTO collection LIMIT 3;
     EXIT WHEN collection.COUNT = 0;

     /* Process data from `collection` */

  END LOOP;
  CLOSE cur;
END;

示例:

DECLARE
  TYPE col_typ IS table of NUMBER;
  collection col_typ;
  v_query varchar2(3000); 
  cur sys_refcursor;
  i int := 0;
  x int;
BEGIN
  v_query := 'SELECT level AS x FROM dual CONNECT BY LEVEL <=10';

  OPEN cur FOR v_query;
  LOOP
     FETCH cur BULK COLLECT INTO collection LIMIT 3;
     EXIT WHEN collection.COUNT = 0;

     /* Process data from `collection` */
     i := i + 1;
     DBMS_OUTPUT.PUT_LINE('==== Batch nbr #' || i );
     FOR x IN 1 .. collection.COUNT LOOP
       DBMS_OUTPUT.PUT_LINE( collection( x ) );
     END LOOP;
  END LOOP;
  CLOSE cur;
END;
/

结果:

==== Batch nbr #1
1
2
3
==== Batch nbr #2
4
5
6
==== Batch nbr #3
7
8
9
==== Batch nbr #4
10

答案 1 :(得分:0)

您可以使用DBMS_SQL执行此操作。但是,您必须检查游标变量。

DECLARE

  src_cur SYS_REFCURSOR;
  curid NUMBER;
  v_query varchar2(3000); 
  ret NUMBER;

BEGIN
  -- DBMS_SQL.OPEN_CURSOR
  curid := DBMS_SQL.OPEN_CURSOR;
  v_query := 'select 1 from dual';

  DBMS_SQL.PARSE(curid, v_query, DBMS_SQL.NATIVE);
  ret := DBMS_SQL.EXECUTE(curid);

  -- Switch from DBMS_SQL to native dynamic SQL
  src_cur := DBMS_SQL.TO_REFCURSOR(curid);

  -- Fetch with native dynamic SQL
  FETCH src_cur BULK COLLECT INTO ... LIMIT x;

  ...