我有一组存在查询的查询。 现在我想通过使用forall以下面显示的方式执行此操作:
open EX01_CURSOR;
LOOP
FETCH EX01_CURSOR BULK COLLECT INTO Queries LIMIT 50000;
EXIT WHEN Queries.COUNT = 0;
FORALL i IN 1 .. Queries.count
**execute immediate Queries(i).update_query;**
commit;
END LOOP;
close EX01_CURSOR;
我想在forall块中执行我的查询。 我收到编译错误,如下所示:
有人可以帮忙吗?没有BULK In-BIND的DML语句不能在FORALL
中使用
答案 0 :(得分:0)
FORALL
实际上不是LOOP
或迭代器,而是BULK
DML
操作。它不会为集合中的每个条目(逐个条目)运行操作,而是对集合中的所有条目运行一个DML操作。您无法在Dynamic SQL
中运行BULK
,也无法进行迭代。要迭代并运行EXECUTE IMMEDIATE
,您需要使用LOOP
(或采用其他方法)。
这是一个例子。它仍使用BULK COLLECT
来控制提交大小,但在Dynamic SQL
中使用FOR LOOP
。 (注意:执行此卷动态SQL效率不高。只是保留原始集合大小的示例)
设置测试数据:
CREATE TABLE TEST_TABLE (
TEST_ID NUMBER
);
INSERT INTO TEST_TABLE SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL <= 50001;
初始数据:
SELECT * FROM TEST_TABLE ORDER BY 1 DESC FETCH FIRST 5 ROWS ONLY;
TEST_ID
50001
50000
49999
49998
49997
然后运行块。这不会使用FORALL
BULK DML
。它使用FOR LOOP
代替:
DECLARE
CURSOR EX01_CURSOR IS (
SELECT 'UPDATE TEST_TABLE SET TEST_TABLE.TEST_ID = TEST_TABLE.TEST_ID + 100000 WHERE TEST_TABLE.TEST_ID = ' ||
TEST_TABLE.TEST_ID AS UPDATE_QUERY
FROM TEST_TABLE);
TYPE EX01_CUR_TYPE IS TABLE OF EX01_CURSOR%ROWTYPE;
QUERIES EX01_CUR_TYPE;
BEGIN
QUERIES := EX01_CUR_TYPE();
OPEN EX01_CURSOR;
LOOP
FETCH EX01_CURSOR BULK COLLECT INTO QUERIES LIMIT 50000;
EXIT WHEN QUERIES.COUNT = 0;
FOR UPDATE_POINTER IN 1..QUERIES.COUNT
LOOP
EXECUTE IMMEDIATE QUERIES(UPDATE_POINTER).UPDATE_QUERY;
END LOOP;
COMMIT;
END LOOP;
CLOSE EX01_CURSOR;
END;
/
PL/SQL procedure successfully completed.
结果:
SELECT * FROM TEST_TABLE ORDER BY 1 DESC FETCH FIRST 5 ROWS ONLY;
TEST_ID
150001
150000
149999
149998
149997