У меня проблема с 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: неправильный тип данных.
Так вопрос у меня есть две части: на самом деле
Почему система генерируется пользователем определенный тип работы для
select
, но не дляmember of
?Почему тип должен быть SQL , а не PL/SQL-тип в пакете ? Я действительно не определяю типы , что часто может быть простым ответом на этот вопрос .
Я думаю, что часть причины, по которой я думал, что часть 2 может быть возможной, заключается в том, что я использовал типы PL/SQL в прошлом в SQL, но это с функциями PIPELINED, где, я думаю, ключевое слово TABLE() действует бит моста между мирами SQL и PL/SQL в этом случае. –
В конвейерной функции неявно создаются типы SQL. http://blog.sydoracle.com/2007/03/pipelined-functions-implicitly-create.html –
@Gary Спасибо за ссылку. Я становлюсь все более и более запутанным днем с взаимодействием между SQL и PL/SQL! –