Как выбрать тип таблицы записей массового сбора

У меня есть процедура, в которой мне нужно кэшировать некоторые данные по соображениям производительности для последующих операций.

Определения TYPE работают

BULK COLLECT INTO работает

SELECT не работает

PROCEDURE MYPROC((PARAMS))AS

  TYPE REC_TYPE IS RECORD (
    COLUMN_1 (TABLEA.COLUMN_A)%TYPE,
    COLUMN_2 (TABLEA.COLUMN_B)%TYPE
  );

  TYPE TAB_TYPE IS TABLE OF REC_TYPE;

  TABLE_1 TAB_TYPE;

BEGIN

  SELECT  COLUMN_A, COLUMN_B
  BULK COLLECT INTO TABLE_1 
  FROM  TABLE_A;

  SELECT * FROM TABLE_1;

END MYPROC;

Урожайность:

Ошибка (#, #): PL/SQL: ORA-00942: таблица или представление не существует

Я также пытался обернуть его в табличную функцию, как я делаю с моими типами с одним столбцом в другом месте, но это тоже не сработало.

SELECT * FROM TABLE(TABLE_1);

Ошибка (#, #): PL/SQL: ORA-22905: невозможно получить доступ к строкам из невложенного элемента таблицы


person Tom Halladay    schedule 21.06.2017    source источник


Ответы (1)


Ваша проблема на самом деле является ошибкой PLS-00642, а не ORA-22905. По сути, вы не можете использовать локальные типы коллекций в операторах SQL. Поэтому решение состоит в том, чтобы определить ваши типы на уровне схемы. При определении типов таким образом мы не можем использовать синтаксис %TYPE и вместо этого должны явно определять столбец (Получение ошибки PLS-00201 при создании типа в oracle), т.е.

create or replace type rec_type as object (
  COLUMN_1 integer,
  COLUMN_2 varchar2(128)
);

create or replace type tab_type as table of rec_type;

Затем вам нужно явно преобразовать значения в соответствующий тип, чтобы выполнить массовый сбор, как указано здесь: ORA-00947 Недостаточно значений при глобальном объявлении типа.

Таким образом, ваша процедура будет выглядеть примерно так:

PROCEDURE MYPROC((PARAMS))AS
  TABLE_1 TAB_TYPE;
  lCount  integer;
BEGIN

  SELECT  REC_TYPE(COLUMN_A, COLUMN_B)
  BULK COLLECT INTO TABLE_1 
  FROM  TABLE_A;

  SELECT COUNT(*) INTO lCount FROM TABLE(TABLE_1);
END MYPROC;
person Chrisrs2292    schedule 22.06.2017
comment
Спасибо за этот ответ! Я скептически отнесся к тому, что невозможно определить встроенный объект, но, увы, это правда: Возможно ли создавать типы объектов Oracle Database внутри PL/SQL? Вы даже не можете создать объект глобально и таблицу встроенную, иначе вы получите Error(#,#): PLS-00642: local collection types not allowed in SQL statements - person Tom Halladay; 22.06.2017