我想从表中获取一些行到游标中,完成所需的工作后,我想清空游标,以便再次使用游标。整个过程将在一个循环内。我已经搜索了很多次,但是没有得到想要的帖子。我想我已经明确表示自己想要什么。简而言之,我想将光标视为Java中的ArrayList。
smj1588 回答:如何从PLSQL Oracle Procedure中删除数据或清空游标?
正如其他人所述,您需要将光标提取到集合中(或不使用显式光标,并且直接使用INTO进行批量收集(见下文)。将其放入集合中后,您可以遍历并删除条目PL / SQL集合具有与Java中的Iterator一起工作的第一个和下一个功能,因此您可以在遍历它们时删除条目。
DECLARE
-- table definition
TYPE t_obj_tab IS TABLE OF all_objects%ROWTYPE;
v_obj_tab t_obj_tab;
-- local variables
v_index INTEGER;
BEGIN
-- get some data into a collection
SELECT *
BULK COLLECT
INTO v_obj_tab
FROM all_objects
WHERE rownum <= 500;
-- log the count for demonstration
dbms_output.put_line(v_obj_tab.count);
-- get the index of the first element in the collection
v_index := v_obj_tab.first;
-- loop through the collection
WHILE v_index IS NOT NULL
LOOP
-- delete objects with some criteria
IF v_obj_tab(v_index).object_name LIKE '%E%' THEN
v_obj_tab.delete(v_index);
END IF;
-- get next element of collection
v_index := v_obj_tab.next(v_index);
END LOOP;
-- log the count to see if any were deleted
dbms_output.put_line(v_obj_tab.count);
END;
/
-- 500
-- 206
您应该注意,将大量对象提取到集合中会占用一定比例的内存。 PL / SQL收集应该尽可能地小(个人而言,我喜欢500行用于批量处理,但是您应该进行基准测试)。建议不要使用过程来提取数据并按程序对其进行过滤,而应使用SQL来过滤结果,以仅返回您感兴趣的行(也提到了其他行)。
我想您也在问如何多次处理同一组数据。如果要这样做,可以创建第二个集合变量,将其设置为第一个(创建副本),并将其保留为原始集合。处理完毕后,您可以使用它来获取原始行并对其进行一些不同的处理。
DECLARE
-- table definition
TYPE t_obj_tab IS TABLE OF all_objects%ROWTYPE;
v_obj_tab t_obj_tab;
v_obj_tab_2 t_obj_tab;
-- local variables
v_index INTEGER;
BEGIN
-- get some data into a collection
SELECT *
BULK COLLECT
INTO v_obj_tab
FROM all_objects
WHERE rownum <= 500;
-- copy!
v_obj_tab_2 := v_obj_tab;
-- log the count for demonstration
dbms_output.put_line(v_obj_tab.count);
-- get the index of the first element in the collection
v_index := v_obj_tab.first;
-- loop through the collection
WHILE v_index IS NOT NULL
LOOP
-- delete objects with some criteria
IF v_obj_tab(v_index).object_name LIKE '%E%' THEN
v_obj_tab.delete(v_index);
END IF;
-- get next element of collection
v_index := v_obj_tab.next(v_index);
END LOOP;
-- log the count to see if any were deleted
dbms_output.put_line(v_obj_tab.count);
dbms_output.put_line(v_obj_tab_2.count);
END;
/
-- 500
-- 206
-- 500 (copy count)