Search code examples
sqloracleplsqlassociative-array

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


The associative array indexed by VARCHAR2(32000) store only 9 elements in this code below. while if i used an associative array indexed by pls_integer, I can store more than 9 elements (in my case 15 elements) in the data structure.

So why an associative array which use VARCHAR2 index dosen't accept more than 9 elements in my example.

code:

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;

Here is what I got in the console:

[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

so why wtabperson.last block at 9 .

If I use this type in my example:

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

I got the expected result:

[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

Could any one explain me this unexpected behaviour of wtabperson.last when I used an associative array with VARCHAR2 index ?

Thanks in advance


Solution

  • You're seeing that because the index is a string; the 15th element you add has index '15', not the number 15; and with string comparison '9' is higher than '15'. So, last is showing the highest string value, which is still '9'. As @Koen sais this is 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.

    where 'highest' and 'lowest' are based on string comparison.

    That has nothing to do with how many elements there are (which is clearly 15); it is only the behaviour of the index value that is affected.

    If you have more elements then you'll see the last value change when you pass 89, as '90' is a higher value than '9', and '91' is higher than '90'; but when you pass 99 it sticks there until you reach 900. And so on.

    db<>fiddle