Существует ряд ограничений для типов коллекций обьявленных в PL/SQL пакетах (здесь и далее локальные коллекции), более подробно описанных в этой секции документации:
As of Oracle Database 12c, it is possible to bind values with PL/SQL-only data types to anonymous blocks (which are SQL statements), PL/SQL function calls in SQL queries and CALL statements, and the TABLE operator in SQL queries.
Допустимо использовать локальные коллекции только в запросах с select. В запросах на изменение данных insert, update, delete и merge ограничения пока не сняты. В документе генеральные направления развития продукта (см. слайд 24), ещё до выхода релиза 12c, этого никто и не обещал:
Cannot bind into insert, update, delete, or merge
В зависимости от поставленной задачи, существуют различные решения.
1. Классика - объявить на уровне схемы
И оба вызова из вопроса с удалением имени пакета в declare секции:
nt numtab := numtab (10,20,30);
будут работать.
2. Использовать табличные функции
Как и ранее, возможно использовать в DML выражениях табличные функции возвращающие как тип результата локальные вложенные таблицы. Но передавать как аргумент функции такого типа, было и пока остаётся, недопустимо:
Такой вызов будет работать:
3. Использовать PL/SQL bulk DML
Предположим, надо получить результаты вставки, например, id сгенерированного неявно. Оператор returning в массовой вставке из подзапроса select, не поддерживается. Выражение forall insert пока единственный путь произвести изменения массово и вернуть результат проведённых изменений, и здесь локальные типы коллекций очень даже кстати:
Дополнение: объявление коллекции на уровне схемы невозможно
Если коллекция содержит типы элементов, которые известны только в PL/SQL контексте, то и объявить такую коллекцию возможно только локально. Например, коллекция с типом элементов rowtype теперь работает с table оператором:
Как использовать в DML выражениях, см. решения 2 и 3.
PS проверялось на серверах: 11.2, 12.1, 12.2, 18.3.
Источник здесь.
0 Комментарии