为什么由 VARCHAR2 索引的关联数组存储的元素不超过 9 个

why an Associative array indexed by VARCHAR2 doesn't store more than 9 elements

VARCHAR2(32000) 索引的关联数组在下面的代码中仅存储 9 个元素。 而如果我使用由 pls_integer 索引的关联数组,我可以在数据结构中存储超过 9 个元素(在我的例子中是 15 个元素)。

那么为什么在我的示例中使用 VARCHAR2 索引的关联数组不接受超过 9 个元素。

代码:

declare
--TYPE tabperson IS TABLE OF varchar2(8) INDEX BY pls_integer;
TYPE tabperson IS TABLE OF varchar2(8) INDEX BY varchar2 (32000);
wtabperson tabperson ;
begin
   FOR i IN 1..15
     LOOP
        wtabperson(i) := 'A' || i;

        dbms_output.PUT_LINE(
                    'i---------> ' || 'size ' || wtabperson.last || ' content ' || 
                      wtabperson(i));
    end loop;
end;

这是我在控制台中得到的:

[2021-06-14 11:32:59] i---------> size 1 content A1
[2021-06-14 11:32:59] i---------> size 2 content A2
[2021-06-14 11:32:59] i---------> size 3 content A3
[2021-06-14 11:32:59] i---------> size 4 content A4
[2021-06-14 11:32:59] i---------> size 5 content A5
[2021-06-14 11:32:59] i---------> size 6 content A6
[2021-06-14 11:32:59] i---------> size 7 content A7
[2021-06-14 11:32:59] i---------> size 8 content A8
[2021-06-14 11:32:59] i---------> size 9 content A9
[2021-06-14 11:32:59] i---------> size 9 content A10
[2021-06-14 11:32:59] i---------> size 9 content A11
[2021-06-14 11:32:59] i---------> size 9 content A12
[2021-06-14 11:32:59] i---------> size 9 content A13
[2021-06-14 11:32:59] i---------> size 9 content A14
[2021-06-14 11:32:59] i---------> size 9 content A15

所以为什么 wtabperson.last 在 9 阻塞。

如果我在示例中使用此类型:

TYPE tabperson IS TABLE OF varchar2(8) INDEX BY pls_integer

我得到了预期的结果:

[2021-06-14 11:39:43] i---------> size 1 content A1
[2021-06-14 11:39:43] i---------> size 2 content A2
 //
[2021-06-14 11:39:43] i---------> size 8 content A8
[2021-06-14 11:39:43] i---------> size 9 content A9
[2021-06-14 11:39:43] i---------> size 10 content A10
[2021-06-14 11:39:43] i---------> size 11 content A11
[2021-06-14 11:39:43] i---------> size 12 content A12
[2021-06-14 11:39:43] i---------> size 13 content A13
[2021-06-14 11:39:43] i---------> size 14 content A14
[2021-06-14 11:39:43] i---------> size 15 content A15

当我使用带有 VARCHAR2 索引的关联数组时,有人能解释一下 wtabperson.last 的这种意外行为吗?

提前致谢

您在控制台中得到了您所要求的内容:)

可以存储9个以上的元素

是的,您可以...检查计数器值:

declare
TYPE tabperson IS TABLE OF varchar2(8) INDEX BY varchar2 (32000);
wtabperson tabperson ;
begin
   FOR i IN 1..15
     LOOP
        dbms_output.PUT_LINE('i---------> ' || 'size ' || i || ' content ' || wtabperson(i));
    end loop;
end;

现在...为什么您只看到 9 作为集合中的最后一个值?那是因为根据documentation对于以字符串索引的关联数组,第一个和最后一个元素分别是具有最低和最高键值的元素。

由于索引为 VARCHAR2,因此 9 高于 10。因此您看到的是 9,它是最高值。按 pls_integer 索引,其工作方式如下所示:

declare
  TYPE tabperson IS TABLE OF varchar2(30) INDEX BY varchar2 (32000);
  TYPE tabpersonibn IS TABLE OF varchar2(30) INDEX BY pls_integer;
  wtabperson tabperson ;
  wtabpersonibn tabpersonibn ;
begin
   FOR i IN 8..11
     LOOP
        wtabperson(i) := 'by VARCHAR2' || i;
        wtabpersonibn(i) := 'by PLS_INTEGER' || i;
        dbms_output.PUT_LINE('i---------> ' || 'size ' || wtabperson.last || ' content ' || wtabperson(i));
        dbms_output.PUT_LINE('i---------> ' || 'size ' || wtabpersonibn.last || ' content ' || wtabpersonibn(i));
    end loop;
end;
/

i---------> size 8 content by VARCHAR28
i---------> size 8 content by PLS_INTEGER8
i---------> size 9 content by VARCHAR29
i---------> size 9 content by PLS_INTEGER9
i---------> size 9 content by VARCHAR210
i---------> size 10 content by PLS_INTEGER10
i---------> size 9 content by VARCHAR211
i---------> size 11 content by PLS_INTEGER11

您看到 因为索引是一个字符串;您添加的第 15 个元素的索引为“15”,而不是数字 15;并且与字符串比较 '9' 高于 '15'。因此,last 显示最高的 string 值,仍然是“9”。正如@Koen 所说,这是 the documented behaviour:

For an associative array indexed by PLS_INTEGER, the first and last elements are those with the smallest and largest indexes, respectively. For an associative array indexed by string, the first and last elements are those with the lowest and highest key values, respectively.

其中 'highest' 和 'lowest' 基于 string comparison

这与 many 个元素无关(显然是 15 个);只有索引值的行为受到影响。

如果您有更多元素,那么当您超过 89 时,您会看到 last 值发生变化,因为“90”​​的值高于“9”,而“91”的值高于“90” ';但是当你超过 99 时,它会一直保持到 900。依此类推。

db<>fiddle