Oracle собирать функции и типы - PullRequest
2 голосов
/ 24 ноября 2010

У меня проблема с Oracle 10g и использованием функции COLLECT. Я только узнал о его существовании сегодня утром, но у меня есть проблема, которую можно решить, используя ее в сочетании с условием member of.

Первоначально я написал код, показанный ниже, который вернулся с ошибкой «ORA_00932: несовместимые типы данных: ожидаемый UDT получил -».

with my_tab as (
  select 1 as cola, 1 as colb from dual union all
  select 1 as cola, 2 as colb from dual union all
  select 2 as cola, 3 as colb from dual union all
  select 2 as cola, 4 as colb from dual union all
  select 3 as cola, 3 as colb from dual union all
  select 3 as cola, 4 as colb from dual union all
  select 4 as cola, 1 as colb from dual union all
  select 4 as cola, 2 as colb from dual 
)
select 
  cola, 
  colb_vals
from (
  select 
    cola, 
    collect(colb) as colb_vals
  from my_tab
  group by cola
)
where 2 member of colb_vals

Мне показалось это немного странным, поскольку в Oracle 10.2.4.0 кажется, что база данных создаст временный системный сгенерированный пользовательский тип и будет его использовать. Если я уберу условие (where 2 member of colb_vals), код будет запущен и покажет, что полученные данные включают временный UDT (с именем SYSTPblahblahblah ==).

После небольшого поиска я понял, что могу решить эту проблему, используя CREATE TYPE, а затем с помощью функции CAST изменить тип вложенной таблицы. Который работал.

Это было использование CREATE TYPE number_ntt as TABLE OF NUMBER; и замена collect(colb) на cast(collect(colb) as number_ntt)

Затем я попытался использовать вложенный тип таблицы, созданный в пакете, поскольку мне нужно, чтобы этот тип был доступен только для одного конкретного запроса в одной процедуре в одном пакете. И я не мог заставить его работать.

create or replace package mike_temp_pkg as
  type number_ntt is table of number;
end mike_temp_pkg;

И на этот раз заменив collect(colb) на cast(collect(colb) as mike_temp_pkg.number_ntt)

В результате ORA-00932: неверный тип данных.

Итак, мой вопрос состоит из двух частей:

  1. Почему система генерирует пользователя определенный тип работы для select но не для member of?

  2. Почему тип должен быть SQL тип, а не тип PL / SQL в пакет? Я действительно не определяю типы что часто так может быть простой ответ на этот вопрос.

1 Ответ

2 голосов
/ 24 ноября 2010

(1)

Документация функции COLLECT гласит: «Чтобы получить результаты этой функции, вы должны использовать ее в функции CAST». Я подозреваю, что он просто не предназначен для поддержки каких-либо целей, кроме простого дампа его содержимого, если только вы не приведете его к определенному типу.

(2)

Анализатор SQL не знает и не имеет доступа к типам, определенным в блоках PL / SQL. Даже когда вы выполняете оператор SQL внутри кода PL / SQL, этот оператор по существу передается независимому анализатору (с заменой имен переменных PL / SQL на заполнители переменных связывания).

...