为什么关联数组中的最后一个元素(索引为table)没有被打印出来?

Why is the last element in associative array (index by table) not printed by?

这似乎是一件基本的事情,但我无法弄清楚。 我有一个如下所示的 PLSQL 代码块。它创建一个简单的稀疏关联数组,并在下标处存储 5 个元素为 -1,0,1,2,100。

打印 ARRAY.LAST 给出 100,ARRAY.COUNT 给出 5。在我的 while 循环中,它正确地打印了所有元素。 但是从 ARRAY.FIRST 到 ARRAY.LAST 的 For 循环仅打印连续下标处的元素直到 2,即使 ARRAY.LAST 给出 100

DECLARE
    TYPE assoc_array IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
    table1 assoc_array;
    i BINARY_INTEGER;
BEGIN
    table1(-1) := 100;
    table1(0) := 101;
    table1(1) := 102;
    table1(2) := 103;
    table1(100) := 104;

    i := table1.FIRST;

    dbms_output.put_line(table1.FIRST);
    dbms_output.put_line(table1.LAST);
    dbms_output.put_line(table1.COUNT);

    i := table1.first;

    while (i is not null)
    loop
        dbms_output.put_line( table1(i) );
        i := table1.next(i);
    end loop;

    dbms_output.put_line( '***');

    for i IN table1.FIRST .. table1.LAST
    loop
        dbms_output.put_line(table1(i) );
    end loop;
END;

输出如下:

-1
100
5
100
101
102
103
104
***
100
101
102
103

将此代码段添加到您的块中以查看原因,即 ORA-01403:

  ...
EXCEPTION 
  WHEN no_data_found THEN
    dbms_output.put_line(sqlerrm);
END;

你的循环没有遍历有效的数组索引。它从 -1 .. 100 循环,当您尝试访问 table1(3) 时,您不能。

或者,您可以运行这样:

FOR i IN table1.FIRST .. table1.LAST LOOP
  IF table1.EXISTS(i) THEN 
    dbms_output.put_line(table1(i));
  END IF;
END LOOP;

但这不是一个好主意,因为遍历您已知不是关联数组索引的所有整数值是非常低效的。

ARRAY.FIRST 是数组中最小的索引号,因此在您的情况下它将是 -1。另一方面,ARRAY.LAST 取了最大的索引号 (100)。

然后FOR循环从最小索引到最大索引,步长为1。但是当它到达一个不存在的索引时,它会抛出异常。

因此只需在循环中添加一个 IF 语句来检查特定索引处的元素是否存在。

IF array.EXISTS(i) THEN
  -- do something
 null;
END IF;