Как выполнить итерацию по именам атрибутов локально объявленных коллекций?
Как выполнить итерацию по именам атрибутов локально объявленных коллекций?
Пробую так, но работает не так, как ожидалось:
declare
type books is record
(title varchar(50) := 'First Book'
,author varchar(50) := 'Me'
,subject varchar(100) := 'Simple ones'
,book_id number := 94321
);
type table_of_books is table of books;
list_of_books table_of_books;
CURSOR c IS
SELECT COLUMN_NAME
FROM ALL_COL_COMMENTS
WHERE table_name='list_of_books';
begin
dbms_output.enable;
list_of_books := table_of_books();
list_of_books.extend(1);
list_of_books(1) := books();
FOR current_field IN c LOOP
dbms_output.put_line(current_field.column_name);
END LOOP;
end;
/
Этот код выполняется, но не выводит ничего.
PS Версия Oracle 19c.
Свободный перевод вопроса Iterate on column names of locally defined table от участника @user5507535
Ответы (1 шт):
Короткий ответ - так как в вопросе, сделать нельзя. Атрибуты типов, объявленныx в PL/SQL блоке, не сохраняются как метаданные в словаре данных БД.
Возможное решение -- получить имена столбцов, в результате т.н. unnesting query c коллекцией в операторе TABLE. Но для этого коллекция должна быть известна SQL парсеру, т.е. как минимум объявлена в пакете. Данные в коллекции в этом случае не нужны, достаточно только открыть курсор:
create or replace package pack as
type book is record (
title varchar(50),
author varchar(50),
subject varchar(100),
book_id number);
type books is table of book index by pls_integer;
end;
/
declare
lib pack.books := pack.books ();
nc number;
cols number;
ds dbms_sql.desc_tab;
rc sys_refcursor;
begin
open rc for select * from table (lib);
nc := dbms_sql.to_cursor_number (rc);
dbms_sql.describe_columns (nc, cols, ds);
dbms_sql.close_cursor (nc);
for i in 1..cols loop dbms_output.put_line (ds(i).col_name);
end loop;
end;
/
Результат:
TITLE
AUTHOR
SUBJECT
BOOK_ID