0

我想使用DELETE CollectionMethod 删除集合中的一些元素,例如:

create or replace procedure testloop3 (clearaaa out nestedtable) as
type nestedtable is table of varchar2(255);
reply_ref_messageIds nestedtable; 
getDelete_messageIds nestedtable;   
begin 
 select distinct r.messagebox_id bulk collect into reply_ref_messageIds from reply r;
 select m.id bulk collect into  getDelete_messageIds from messagebox m;
        getDelete_messageIds.delete(2);
   getDelete_messageIds.delete(4);
   getDelete_messageIds.delete(7);
    getDelete_messageIds.delete(11);
     getDelete_messageIds.delete(13);
    for i in getDelete_messageIds.FIRST .. getDelete_messageIds.LAST loop
  dbms_output.put_line(i);
end loop;
for i in 5 .. 12 loop
  dbms_output.put_line(i);
end loop;
end;

然后我用 plsql dev 调试这个过程

-- Created on 2013/4/4 by THINKPAD 
declare 
  -- Local variables here
 aa nestedtable;
begin
  -- Test statements here
  testloop3(aa);
end;

我得到了getDelete_messageIds删除前的索引,它们是 1 到 15。

但是:当我调试getDelete_messageIds.delete(2);它时,它会删除索引 1 和 2 ......我无法解释为什么。
然后当我调试下一条语句时getDelete_messageIds.delete(4);,它会删除索引 3 和 4。然后getDelete_messageIds.delete(7);只删除索引 7 ......
我无法理解......

4

2 回答 2

1

如发布的那样,您的程序没有显示任何此类内容。你只是像循环一样

for idx in 1..15 loop

(.FIRST 将解析为 1,.LAST 将解析为 15)。这并不意味着 NT 中仍有 15 个元素。

您没有检查索引是否已删除。我认为您对遍历存在间隙的嵌套表的正确方法感到困惑。

即你可以看到元素被删除:

SQL> create table messagebox(id ) as select to_char(rownum) from dual connect by level <= 15;

Table created.

SQL> create or replace procedure testloop3
  2  as
  3    type nestedtable is table of varchar2(255);
  4    getDelete_messageIds nestedtable;
  5    v_idx number;
  6  begin
  7      select m.id bulk collect into  getDelete_messageIds from messagebox m;
  8      getDelete_messageIds.delete(2);
  9      getDelete_messageIds.delete(4);
 10      getDelete_messageIds.delete(7);
 11      getDelete_messageIds.delete(11);
 12      getDelete_messageIds.delete(13);
 13      v_idx := getDelete_messageIds.first;
 14      while v_idx is not null
 15      loop
 16        dbms_output.put_line(v_idx);
 17        v_idx := getDelete_messageIds.next(v_idx);
 18      end loop;
 19  end;
 20  /

Procedure created.

SQL> exec testloop3
1
3
5
6
8
9
10
12
14
15

所以 2, 4, 7, 11, 13 被删除。完全符合预期。

于 2013-04-04T16:19:36.463 回答
1

你可以看到

DECLARE
   TYPE NumList IS TABLE OF NUMBER;
   n NumList := NumList(1,3,5,7);
   counter INTEGER;
BEGIN
   DBMS_OUTPUT.PUT_LINE('N''s first subscript is ' || n.FIRST);
   DBMS_OUTPUT.PUT_LINE('N''s last subscript is ' || n.LAST);
-- When the subscripts are consecutive starting at 1, 
-- it's simple to loop through them.
   FOR i IN n.FIRST .. n.LAST
   LOOP
      DBMS_OUTPUT.PUT_LINE('Element #' || i || ' = ' || n(i));
   END LOOP;
   n.DELETE(2); -- Delete second element.
-- When the subscripts have gaps
-- or the collection might be uninitialized,
-- the loop logic is more extensive.
-- Start at the first element
-- and look for the next element until there are no more.
   IF n IS NOT NULL THEN
      counter := n.FIRST;
      WHILE counter IS NOT NULL
      LOOP
         DBMS_OUTPUT.PUT_LINE
           ('Element #' || counter || ' = ' || n(counter));
         counter := n.NEXT(counter);
      END LOOP;
   ELSE
      DBMS_OUTPUT.PUT_LINE('N is null, nothing to do.');
   END IF;
END;

参考查找第一个或最后一个集合元素

于 2013-06-02T06:22:49.847 回答