Ответ 1
Я предполагаю, что это должно привести к печати "Нулевой ассоциативный массив". Это предположение неверно для ассоциативных массивов. Они существуют, когда объявляются, но пусты. Это было бы правильно для других типов коллекций PL/SQL:
Пока вы не инициализируете его, вложенная таблица или varray атомарно нуль; сама коллекция является нулевой, а не ее элементами. Чтобы инициализировать вложенной таблицы или varray, вы используете конструктор, определяемый системой с тем же именем, что и тип коллекции. Эта функция создает коллекции из переданных ему элементов.
Вы должны явно вызвать конструктор для каждого varray и вложенного переменная таблицы. Ассоциативные массивы, третий тип коллекции, do не использовать конструкторы. Конструкторские вызовы разрешены везде, где функция звонки разрешены. Инициализация и ссылки на коллекции
Для сравнения:
SQL> declare
2 type varchar2_100_aa is table of varchar2(100) index by binary_integer;
3 test varchar2_100_aa;
4 begin
5 test(1) := 'Hello';
6 dbms_output.put_line(test(1));
7 end;
8 /
Hello
PL/SQL procedure successfully completed.
SQL> declare
2 type varchar2_100_va is varray(100) of varchar2(100);
3 test varchar2_100_va;
4 begin
5 test(1) := 'Hello';
6 dbms_output.put_line(test(1));
7 end;
8 /
declare
*
ERROR at line 1:
ORA-06531: Reference to uninitialized collection
ORA-06512: at line 5
Переменная массив выполнена правильно:
SQL> declare
2 type varchar2_100_va is varray(10) of varchar2(100);
3 test varchar2_100_va;
4 begin
5 test := varchar2_100_va(); -- not needed on associative array
6 test.extend; -- not needed on associative array
7 test(1) := 'Hello';
8 dbms_output.put_line(test(1));
9 end;
10 /
Hello
PL/SQL procedure successfully completed.
Поскольку ассоциативный массив пуст first
и last
равны нулю, вот почему ваш второй пример приводит к ORA-06502: PL/SQL: Numeric or value error
:
SQL> declare
2 type varchar2_100_aa is table of varchar2(100) index by binary_integer;
3 test varchar2_100_aa;
4 begin
5 dbms_output.put_line(test.count);
6 dbms_output.put_line(coalesce(to_char(test.first), 'NULL'));
7 dbms_output.put_line(coalesce(to_char(test.last), 'NULL'));
8 test(1) := 'Hello';
9 dbms_output.new_line;
10 dbms_output.put_line(test.count);
11 dbms_output.put_line(coalesce(to_char(test.first), 'NULL'));
12 dbms_output.put_line(coalesce(to_char(test.last), 'NULL'));
13 end;
14 /
0
NULL
NULL
1
1
1
PL/SQL procedure successfully completed.
EDIT Также обратите внимание, что ассоциативные массивы могут быть разрежены. Цикл между номерами first
и last
приведет к возникновению исключения для любой редкой коллекции. Вместо этого используйте first
и next
следующим образом: (last
и prev
для петли в другом направлении.)
SQL> declare
2 type varchar2_100_aa is table of varchar2(100) index by binary_integer;
3 test varchar2_100_aa;
4 i binary_integer;
5 begin
6 test(1) := 'Hello';
7 test(100) := 'Good bye';
8 dbms_output.put_line(test.count);
9 dbms_output.put_line(coalesce(to_char(test.first), 'NULL'));
10 dbms_output.put_line(coalesce(to_char(test.last), 'NULL'));
11 dbms_output.new_line;
12 --
13 i := test.first;
14 while (i is not null) loop
15 dbms_output.put_line(to_char(i, '999') || ' - ' || test(i));
16 i := test.next(i);
17 end loop;
18 end;
19 /
2
1
100
1 - Hello
100 - Good bye
PL/SQL procedure successfully completed.