2010-11-24 3 views
2

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

Первоначально я написал код, показанный ниже, который вернулся с ошибкой «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, то кажется, что база данных будет создавать временную систему, порожденную определенный пользователем тип, и использовать его. Если я удалю это условие,(), тогда код запустится и покажет извлеченные данные, включая временный 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-тип в пакете ? Я действительно не определяю типы , что часто может быть простым ответом на этот вопрос .

ответ

2

(1)

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

(2)

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

+0

Я думаю, что часть причины, по которой я думал, что часть 2 может быть возможной, заключается в том, что я использовал типы PL/SQL в прошлом в SQL, но это с функциями PIPELINED, где, я думаю, ключевое слово TABLE() действует бит моста между мирами SQL и PL/SQL в этом случае. –

+0

В конвейерной функции неявно создаются типы SQL. http://blog.sydoracle.com/2007/03/pipelined-functions-implicitly-create.html –

+0

@Gary Спасибо за ссылку. Я становлюсь все более и более запутанным днем ​​с взаимодействием между SQL и PL/SQL! –

Смежные вопросы