问题描述
我有一个由包含 12 个元素的字符串索引的关联数组。 但是使用 FirsT 和 LAST 方法不会解析其中存储的所有元素。
declare
TYPE tabperson IS TABLE OF varchar2(8) INDEX BY varchar2 (32000);
wtabperson tabperson ;
begin
FOR i IN 1..12
LOOP
wtabperson(i) := 'A' || i;
end loop;
dbms_output.PUT_LINE('content of index 11: ' || wtabperson('11'));
dbms_output.PUT_LINE('content of index 12: ' || wtabperson('12'));
dbms_output.PUT_LINE('size of the associative array: ' || wtabperson.COUNT);
dbms_output.PUT_LINE(' Now I would like to parse all the content of the associative array
');
for i in wtabperson.FirsT.. wtabperson.LAST
LOOP
dbms_output.PUT_LINE('index ' || i || ' --------------> ' || wtabperson(i));
end loop;
end;
这是我在控制台中得到的:
[2021-07-25 19:05:33] content of index 11: A11
[2021-07-25 19:05:33] content of index 12: A12
[2021-07-25 19:05:33] size of the associative array: 12
[2021-07-25 19:05:33] Now I would like to parse all the content of the associative array
[2021-07-25 19:05:33] index 1 --------------> A1
[2021-07-25 19:05:33] index 2 --------------> A2
[2021-07-25 19:05:33] index 3 --------------> A3
[2021-07-25 19:05:33] index 4 --------------> A4
[2021-07-25 19:05:33] index 5 --------------> A5
[2021-07-25 19:05:33] index 6 --------------> A6
[2021-07-25 19:05:33] index 7 --------------> A7
[2021-07-25 19:05:33] index 8 --------------> A8
[2021-07-25 19:05:33] index 9 --------------> A9
所以关联数组由字符串索引包含 12 个元素: 索引值按以下顺序排列:'1'、'10'、'11'、'12'、'2'、'3'、'4'、'5'、'6'、'7'、'8 ','9'。
wtabperson.LAST 等于 '9' 并且 '11' 低于 wtabperson.LAST 那么为什么我在解析时没有得到 wtabperson('11') 的值数组使用 FirsT 和 LAST 方法?
是否使用 FirsT 和 LAST 方法仅解析数组的一部分(如果是由字符串索引的关联数组)?
为什么使用 FirsT 和 LAST 方法不会解析由字符串索引的关联数组的所有内容? [编辑] 在这篇文章 why-an-associative-array-doesen't-store-more-than-9-elements 中,问题是为什么 wtabpeson.LAST 在 '9' 阻塞,我得到了我的回应。
现在的问题是: 既然索引值 '11' 小于 '9',那么为什么 '11' 不在 wtabperson.FirsT 和 wtabperson.LAST 之间? wtabperson('11') 的值是 A11。那么为什么我在使用 FirsT 和 LAST 解析数组时没有得到索引 '11' 的值?
谢谢
解决方法
如your previous question中所述,the documentation says:
对于由 PLS_INTEGER 索引的关联数组,第一个和最后一个元素分别是具有最小和最大索引的元素。对于以字符串为索引的关联数组,第一个和最后一个元素分别是具有最低和最高键值的元素。
其中“最高”和“最低”基于 string comparison。
对于您的数据,最低值为“1”,最高值为“9”。
所以当你这样做时:
for i in wtabperson.FIRST.. wtabperson.LAST
您的数据实际上是在做:
for i in '1'..'9'
循环是在这两个字符串之间的字符串值上,所以你得到索引键'1'、'2'、'3'、'4'、'5'、'6'、'7'的列表,'8','9'。
但它只查看定义范围的高值和低值。 不 做的是循环遍历 first 和 last 之间的实际索引值。除了获取循环声明中的第一个/最后一个之外,循环不查看集合。您(我认为)期望它获得索引键“1”、“10”、“11”、“12”、“2”……但这不是它的工作原理。循环控制机制不知道 '10'、'11' 和 '12' 存在 - 甚至不知道数组中存在 '2';只是它是'1'之后的下一个字符串。
如果你想遍历所有的索引值,你可以这样做:
declare
...
idx varchar2(8); -- to match your key size
begin
...
idx := wtabperson.FIRST; -- get first element
while idx is not null
loop
dbms_output.PUT_LINE('index ' || idx || ' --------------> ' || wtabperson(idx));
idx := wtabperson.NEXT(idx); -- get next element
end loop;
END LOOP;
一直循环下去,直到索引值用完为止,按排序顺序;并且根本不需要引用 last
。