Вызов ассоциативного массива Oracle из подзапроса ОБНОВЛЕНИЯ приводит к ошибке PLS-00201

#oracle #sql-update #associative-array

Вопрос:

Я пытаюсь найти значения из ассоциативного массива для обновления таблицы, но получаю ошибку. Вот минимальный код, демонстрирующий проблему (мой фактический запрос намного сложнее).

Я что-то упускаю, или если это ограничение Оракула, есть ли способ обойти его?

 CREATE TABLE t_employee AS SELECT cast('john' as varchar2(30)) emp_name, CAST (NULL AS NUMBER (5)) emp_id FROM DUAL;
DECLARE
    TYPE emp_typ IS TABLE OF NUMBER INDEX BY VARCHAR2(30);
    emp_lookup   emp_typ;
BEGIN
    emp_lookup ('john') := 1234;
    UPDATE t_employee e
       SET emp_id = (SELECT emp_lookup (e.emp_name) FROM DUAL);
END;
/

--DROP TABLE t_employee;
 

> PLS-00201: идентификатор «E. EMP_NAME» должен быть объявлен

и когда я изменю обновление на более простую конструкцию:

 UPDATE t_employee SET emp_id = emp_lookup (t_employee.emp_name);
 

Я понимаю эту странность: PLS-00382: выражение неверного типа

То же самое с SELECT. Мне кажется, что мы не можем использовать ассоциативные массивы непосредственно в операторах SQL.

Ответ №1:

Коллекция ассоциативных массивов является типом данных только для PL/SQL; ее нельзя использовать в операторах SQL.

Из документации Oracle:

Таблица 5-1 PL/SQL: Типы коллекций

Тип коллекции Количество элементов Тип индекса Плотный или разреженный Неинициализированный статус Где Определено Может быть Типом данных Атрибута ADT
Ассоциативный массив (или индекс по таблице) Неуточненный Строка или PLS_INTEGER Любой Пустой В блоке или пакете PL/SQL НЕТ
VARRAY (массив переменного размера) Указанный Целое число Всегда плотный Нулевой В блоке или пакете PL/SQL или на уровне схемы Только если определено на уровне схемы
Вложенная таблица Неуточненный Целое число Начинает густеть, может стать редким Нулевой In PL/SQL block or package or at schema level Only if defined at schema level

Ассоциативный массив (ранее называемый таблицей PL/SQL или таблицей по индексу) представляет собой набор пар ключ-значение.

В отличие от таблицы базы данных, ассоциативный массив:

  • Не требует дискового пространства или сетевых операций
  • Невозможно манипулировать с помощью операторов DML

VARRAY и вложенные коллекции таблиц могут использоваться в операторах SQL.

Комментарии:

1. Спасибо MT0 — это то, что я пытался найти в документации, каким-то образом это ускользнуло от меня. Аррр, какая пустая трата утра, пытаясь заставить это работать!