Как-то раньше мне не приходилось сталкиваться с задачей, когда приходилось внутри одной табличной функции запрашивать данные из другой табличной функции в передавать их выше, но в конце концов этот момент настал.
Мне было необходимо перегрузить табличную функцию, а поскольку алгоритм обработки данных полностью повторял уже существующий я решил воспользоваться вызовом табличной функции.
Вроде бы всё просто, делай селект типа:
for foo in (select * from pipelined_function(x))
loop
pipe row (r.a, r.b, r.c ...);
end loop;
Но мне хотелось больше удобства, не хотел я писать кучу этих имён в pipe row, и начались поиски решения. Слава богу знаний хватило на то, чтобы прийти вот к такому решению:
Создаём типы:
create or replace type tr_mixed as object (num number, str varchar2(15));
create or replace type tt_mixed is table of tr_mixed;
Создаём pipelined функцию, из которой в последствии будем получать данные:
create or replace function pipe_func(p_iter number)
return tt_mixed
pipelined
is
begin
for l_index in 1 .. p_iter
loop
pipe row (tr_mixed(l_index, 'str-' || l_index));
end loop;
end pipe_func;
А теперь создаём pipelined функцию, которая будет запрашивать данные из функции выше:
create or replace
function pipe_func_ext
return tt_mixed
pipelined
is
l_temp_tt tt_mixed;
begin
select cast(multiset (select * from table(pipe_func(10))) as tt_mixed)
into l_temp_tt
from dual;
for l_index in l_temp_tt.first .. l_temp_tt.last
loop
pipe row (l_temp_tt(l_index));
end loop;
end pipe_func_ext;
Вся магия заключается в псевдофункции MULTISET, которая используется только 4как аргумент псевдофункции CAST.Она позволяет извлечь из базы данных набор значений и тут же преобразовать его в коллекцию нужного типа. Синтаксис у неё такой:
select cast (multiset (select поле from таблица) as тип_коллекции) from dual
Если всё равно не понятно, то код:
select cast(multiset (select * from table(pipe_func(10))) as tt_mixed)
bulk collect into l_temp_tt
from table(pipe_func(10));
Только весь кайф заключается в том, что с multiset, можно писать *
Проверяем, что всё работает:
select * from table(pipe_func_ext);
Мне было необходимо перегрузить табличную функцию, а поскольку алгоритм обработки данных полностью повторял уже существующий я решил воспользоваться вызовом табличной функции.
Вроде бы всё просто, делай селект типа:
for foo in (select * from pipelined_function(x))
loop
pipe row (r.a, r.b, r.c ...);
end loop;
Но мне хотелось больше удобства, не хотел я писать кучу этих имён в pipe row, и начались поиски решения. Слава богу знаний хватило на то, чтобы прийти вот к такому решению:
Создаём типы:
create or replace type tr_mixed as object (num number, str varchar2(15));
create or replace type tt_mixed is table of tr_mixed;
Создаём pipelined функцию, из которой в последствии будем получать данные:
create or replace function pipe_func(p_iter number)
return tt_mixed
pipelined
is
begin
for l_index in 1 .. p_iter
loop
pipe row (tr_mixed(l_index, 'str-' || l_index));
end loop;
end pipe_func;
А теперь создаём pipelined функцию, которая будет запрашивать данные из функции выше:
create or replace
function pipe_func_ext
return tt_mixed
pipelined
is
l_temp_tt tt_mixed;
begin
select cast(multiset (select * from table(pipe_func(10))) as tt_mixed)
into l_temp_tt
from dual;
for l_index in l_temp_tt.first .. l_temp_tt.last
loop
pipe row (l_temp_tt(l_index));
end loop;
end pipe_func_ext;
Вся магия заключается в псевдофункции MULTISET, которая используется только 4как аргумент псевдофункции CAST.Она позволяет извлечь из базы данных набор значений и тут же преобразовать его в коллекцию нужного типа. Синтаксис у неё такой:
select cast (multiset (select поле from таблица) as тип_коллекции) from dual
Если всё равно не понятно, то код:
select cast(multiset (select * from table(pipe_func(10))) as tt_mixed)
into l_temp_tt
from dual;
можно представить в виде:
select tr_number(num, str)bulk collect into l_temp_tt
from table(pipe_func(10));
Только весь кайф заключается в том, что с multiset, можно писать *
Проверяем, что всё работает:
select * from table(pipe_func_ext);
Комментариев нет:
Отправить комментарий