立即执行中的批量收集限制
Posted
技术标签:
【中文标题】立即执行中的批量收集限制【英文标题】:BULK COLLECT LIMIT in EXECUTE IMMEDIATE 【发布时间】:2015-11-15 09:57:16 【问题描述】:是否可以使用立即执行来限制批量收集?
我有以下脚本,但在使用 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;
如果我的代码无法限制,是否有任何解决方法?
谢谢!
【问题讨论】:
您用“oracle 10g”标记了您的问题,但 LIMIT 子句在 10g 中不可用 【参考方案1】:似乎 EXECUTE IMMEDIATE 语法不允许在批量收集子句中使用 LIMIThttp://docs.oracle.com/cd/E11882_01/appdev.112/e25519/executeimmediate_statement.htm#CJACGJJG
bulk_collect_into_clausehttp://docs.oracle.com/cd/E11882_01/appdev.112/e25519/returninginto_clause.htm#CJAIAGHJ
您可以将光标和 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
【讨论】:
非常感谢您。我仍然不明白为什么限制不适用于立即执行,但我会让我未来的自己弄清楚。不过,只有一个问题,对我的批量收集添加限制会改变我的脚本的性能吗?我添加 LIMIT 的主要目的是避免出现“快照太旧”的 oracle 错误,但我不确定哪个会更快。有限制或没有限制。【参考方案2】:您可以使用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;
...
【讨论】:
以上是关于立即执行中的批量收集限制的主要内容,如果未能解决你的问题,请参考以下文章