简体   繁体   English

如何在 PL/SQL 中编写 FOR EACH 循环?

[英]How to write a FOR EACH loop in PL/SQL?

是否可以在 PL/SQL 数组上运行 for each 循环?

for i in my_array.first ..my_array.last loop
  --do_something with my_array(i);
end loop;

It's no possible to iterate over the associative arrays with a non numeric index with a FOR-loop.不可能使用 FOR 循环遍历具有非数字索引的关联数组。 The solution below works just fine.下面的解决方案工作得很好。

-- for-each key in (associative-array) loop ... 
declare
    type items_type is table of varchar2(32) index by varchar2(32);
    items items_type;
begin
    items('10') := 'item 10';
    items('20') := 'item 20';
    items('30') := 'item 30';
    dbms_output.put_line('items=' || items.count); 

    <<for_each>> declare key varchar2(32); begin loop 
        key := case when key is null then items.first else items.next(key) end; 
        exit when key is null;
        dbms_output.put_line('item(' || key || ')=' || items(key));
        --do something with an item
    end loop; end for_each;
end;

In my opinion 0xdb solution is best.在我看来,0xdb 解决方案是最好的。 Even if you have numeric index it is better to us this construct即使您有数字索引,对我们来说这个结构也更好

DECLARE
  TYPE TTab_SomeTable IS TABLE OF VARCHAR2(2000) INDEX BY PLS_INTEGER;
  --
  vt_SomeTable TTab_SomeTable;
  vi_Idx       NUMBER;
BEGIN
  vt_SomeTable(1) := 'First';
  vt_SomeTable(2) := 'Second';
  vt_SomeTable(5) := 'Fifth';
  vt_SomeTable(10) := 'Tenth';

  
  vi_Idx := vt_SomeTable.FIRST;
  LOOP
    --
    EXIT WHEN vi_Idx IS NULL;
    --
    dbms_output.Put_Line('vt_SomeTable(' || vi_Idx || ') = ' || vt_SomeTable(vi_Idx));
    --
    vi_Idx := vt_SomeTable.NEXT(vi_Idx);
    --
  END LOOP vi_Idx;
END;

It is not susceptible to index discontinuity like below two examples, which will fail on index 3:它不容易受到索引不连续的影响,例如以下两个示例,这将在索引 3 上失败:

DECLARE
  TYPE TTab_SomeTable IS TABLE OF VARCHAR2(2000) INDEX BY PLS_INTEGER;
  --
  vt_SomeTable TTab_SomeTable;
BEGIN
  vt_SomeTable(1) := 'First';
  vt_SomeTable(2) := 'Second';
  vt_SomeTable(5) := 'Fifth';
  vt_SomeTable(10) := 'Tenth';

  -- Throw No_data_found on vi_Idx = 3
  FOR vi_Idx IN vt_SomeTable.FIRST .. vt_SomeTable.LAST
  LOOP
    dbms_output.Put_Line('vt_SomeTable(' || vi_Idx || ') = ' || vt_SomeTable(vi_Idx));
  END LOOP vi_Idx;
END;



DECLARE
  TYPE TTab_SomeTable IS TABLE OF VARCHAR2(2000) INDEX BY PLS_INTEGER;
  --
  vt_SomeTable TTab_SomeTable;
BEGIN
  vt_SomeTable(1) := 'First';
  vt_SomeTable(2) := 'Second';
  vt_SomeTable(5) := 'Fifth';
  vt_SomeTable(10) := 'Tenth';

  -- Throw No_data_found on vi_Idx = 3.
  FOR vi_Idx IN 1 .. vt_SomeTable.COUNT
  LOOP
    dbms_output.Put_Line('vt_SomeTable(' || vi_Idx || ') = ' || vt_SomeTable(vi_Idx));
  END LOOP vi_Idx;
END;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM