Как вручную инициализировать коллекцию RECORD в PL/SQL?
ребята. Здесь простой пример двухмерного массива в PL/SQL, который отлично работает.
declare
type a is table of number;
type b is table of a;
arr b := b(a(1, 2), a(3, 4));
begin
for i in arr.first .. arr.last loop
for j in arr(i).first .. arr(i).last loop
dbms_output.put_line(arr(i) (j));
end loop;
end loop;
end;
Мне нужно сделать что-то подобное для таблицы RECORDS
. Вот так:
type a is record(a1 number, a2 number);
type b is table of a;
Вопрос в том, могу ли я вручную инициализировать этот массив, или он должен быть заполнен bulk collects
или подобным? Тот же синтаксис, что и выше, не работает, и я не смог найти образец инициализации в руководствах.
Ответы
Ответ 1
Синтаксис "конструктора" для RECORD не существует, поэтому вы должны заполнить их следующим образом:
declare
type a is record(a1 number, a2 number);
type b is table of a;
arr b := b();
begin
arr.extend(2);
arr(1).a1 := 1;
arr(1).a2 := 2;
arr(2).a1 := 3;
arr(2).a2 := 4;
end;
Ответ 2
Это работает без объектов, но вам нужно объявить конструктор для значений типа "a".
declare
type a is record(a1 number, a2 number);
type b is table of a;
arr b;
--Constructor for type a
function a_(a1 number, a2 number) return a is
r_a a;
begin
r_a.a1 := a1;
r_a.a2 := a2;
return(r_a);
end;
begin
arr := b(a_(1, 2), a_(3, 4), a_(5, 6), a_(7, 8));
for i in arr.first .. arr.last loop
dbms_output.put_line(arr(i).a1||', '||arr(i).a2);
end loop;
end;
Ответ 3
Начиная с версии 18c Квалифицированные выражения предоставляет альтернативный способ определения значений сложных типов данных. Цитата:
Начиная с Oracle Database Release 18c, любое значение PL/SQL может быть представлено выражением (например, для записи или для ассоциативного массива), например, конструктор предоставляет абстрактное значение типа данных. В PL/SQL мы используем термины "квалифицированное выражение" и "агрегат", а не термин "конструктор типов" в SQL, но функциональность та же.
Вот рабочий пример:
declare
type a is record (a1 number, a2 number);
type b is table of a index by varchar2 (16);
arr b := b ('key1' => a (1, 2), 'key2' => a (3, 4));
begin
declare key varchar2 (16) := arr.first; begin
<<foreach>> loop
dbms_output.put_line (arr(key).a1||','||arr (key).a2);
key := arr.next (key);
exit foreach when key is null;
end loop; end;
end;
/
PL/SQL procedure successfully completed.
1,2
3,4