Как вызвать конвейерную функцию с результатом другой функции как аргумент? PLS-00306: неверное количество или типы аргументов
Как вызвать конвейерную функцию с результатом другой конвейерной функции в качестве аргумента?
Есть такие пользовательские типы данных:
create or replace TYPE RESULTING_RECORD_RT force as object (
MEASURE VARCHAR2(1024), VALUE NUMBER)
/
create or replace TYPE RESULTING_COLS_RT IS TABLE OF RESULTING_RECORD_RT
/
И пакет с двумя конвейерными функциями:
create or replace package pipe_pkg as
function pipe_func_emp return RESULTING_COLS_RT PIPELINED;
function pipe_func_emp2 (input_Set IN resulting_cols_rt) return RESULTING_COLS_RT PIPELINED;
end;
/
create or replace package body pipe_pkg as
function pipe_func_emp return RESULTING_COLS_RT PIPELINED is
test_tbl resulting_cols_rt:= resulting_cols_rt();
begin
test_tbl(1):=resulting_record_rt('A',1);
test_tbl.extend;
test_tbl(2):=resulting_record_rt('B',2);
PIPE ROW(test_tbl(1));
PIPE ROW(test_tbl(2));
return;
end;
function pipe_func_emp2(input_Set IN resulting_cols_rt) return RESULTING_COLS_RT PIPELINED is
v_tmp VARCHAR2(10240);
l_res SYS_REFCURSOR;
recs resulting_record_rt;
begin
open l_res for select * from table(input_Set);
loop
fetch l_res into recs;
PIPE ROW(recs);
exit when l_res%notfound;
end loop;
close l_res;
return;
end;
end;
/
Когда пытаюсь вызвать одну функцию с другой функцией в качестве аргумента, то получаю ошибку:
select *
from TABLE (pipe_pkg.pipe_func_emp2 (
CURSOR (select * from TABLE (pipe_pkg.pipe_func_emp()))))
ORA-06553: PLS-306: wrong number or types of arguments in call to 'PIPE_FUNC_EMP2'
Что делаю не так?
Свободный перевод вопроса Pipelining Between PL/SQL Table Functions от участника @brungel
Ответы (1 шт):
Автор решения: 0xdb
→ Ссылка
Функция pipe_func_emp2 ожидает RESULTING_COLS_RT в качестве аргумента, но выражение CURSOR создаст REF CURSOR. Это разные типы данных.
Попробуйте простой воспроизводимый пример:
create or replace type somerow as object (id int, val varchar2 (8))
/
create or replace type sometab is table of somerow
/
create or replace package pack as
function func1 return sometab pipelined;
function func2 (cur sys_refcursor) return sometab pipelined;
end;
/
create or replace package body pack as
function func1 return sometab pipelined is
tab sometab := sometab (somerow (1,'AAA'), somerow (2,'BBB'));
begin
for i in 1..tab.count loop
pipe row (tab(i));
end loop;
return;
end;
function func2 (cur sys_refcursor) return sometab pipelined is
sr somerow;
begin
loop
fetch cur into sr;
exit when cur%notfound;
pipe row (sr);
end loop;
close cur;
return;
end;
end;
/
Запрос и его результат:
select *
from table (pack.func2 (
cursor (select value (p) from table (pack.func1()) p)))
/
ID VAL
---------- --------
1 AAA
2 BBB