BULK COLLECT LIMIT in EXECUTE IMMEDIATE

亡梦爱人 提交于 2019-12-23 03:55:12

问题


Is it possible to put a limit in a bulk collect using execute immediate?

I have below script but I am getting error when using a 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;

If limit is not possible with my code, is there any work around?

Thanks!


回答1:


It seems that EXECUTE IMMEDIATE syntax doesn't allow for LIMIT in bulk collect clause

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


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


You can use a cursor and FETCH .. LIMIT command together with OPEN..FOR command,
in this way:

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;

Example:

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

Result:

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



回答2:


You can use the DBMS_SQL to do this. However, you have to go over cursor variables.

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;

  ...


来源:https://stackoverflow.com/questions/33718417/bulk-collect-limit-in-execute-immediate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!