嵌套的 PIPELINED 函数
Nested PIPELINED function
create type data_type_1 as object (x number, y number)
/
create type table_type_1 as table of data_type_1
/
create or replace package xyz AS
function main_xyz return table_type_1 pipelined;
function sub_func return table_type_1 pipelined;
function sub_func1 return table_type_1 pipelined;
end xyz;
/
create package body XYZ AS
function main_xyz return data_type_1 pipelined is
begin
--code
--pipe row(sub_func); --edit_1
FOR rec in (select * from table(sub_func1(x,y))) LOOP
pipe row(rec);
END LOOP;
end;
--function sub_func return data_type_1 pipelined is --edit_1
--begin --edit_1
--code --edit_1
--pipe row(def); --def is data_type_1 --edit_1
--end; --edit_1
function sub_func_1(x in number, y in number) return data_type_1 pipelined is
begin
--code
loop
pipe row(abc); --abc is data_type_1
end loop;
end;
end;
create package body ABC AS
function main_ABC is
begin
--code
FOR rec in (select * from table(main_xyz)) LOOP
pipe row(rec);
END LOOP;
end;
end;
我得到的错误是...
Error is showed in the block of main_xyz where sub_func1 is called.
[Error] PLS-00382 (): PLS-00382: expression is of wrong type
[Error] PLS-00306 (): PLS-00306: wrong number or types of arguments in call to
[Error] ORA-00904 (): PL/SQL: ORA-00904: : invalid identifier
[Error] PLS-00364 (): PLS-00364: loop index variable 'REC' use is invalid
上面的代码有什么问题?为什么?
您的函数正在 returning data_type_1
,并且 table 集合也在尝试使用它。但是两者都需要一个集合类型,即使您希望它们只有 return 一个值(在这种情况下没有太多点流水线)。您不能直接通过管道传输集合类型,而是通过管道传输集合的成员。所以 data_type_1
应该是标量或 object/record 类型,你需要另一种类型,它是这些的集合。
create type data_type_1 as object (x number, y number)
/
create type table_type_1 as table of data_type_1
/
create or replace package xyz AS
function main_xyz return table_type_1 pipelined;
function sub_func return table_type_1 pipelined;
function sub_func1 return table_type_1 pipelined;
end xyz;
/
create or replace package body xyz as
function main_xyz return table_type_1 pipelined is
begin
--code
for rec in (select * from table(sub_func)) loop
pipe row(data_type_1(rec.x, rec.y));
end loop;
for rec in (select * from table(sub_func1)) loop
pipe row(data_type_1(rec.x, rec.y));
end loop;
end;
function sub_func return table_type_1 pipelined is
def data_type_1;
begin
--code
pipe row(def); --def is data_type_1
end sub_func;
function sub_func1 return table_type_1 pipelined is
abc data_type_1;
begin
--code
loop
pipe row (abc); --abc is data_type_1
end loop;
end sub_func1;
end xyz;
/
所以我添加了您现有 data_type_1
的 table 类型,并将函数定义更改为 return 类型 table。 pipe row
仍然使用 data_type_1
- 每个都是 table 类型中的一行。您的循环需要查询其游标,而不是直接调用 table()
,因此我也对其进行了更改。 pipe row(sub_func);
也需要对查询进行类似的循环。
您只将此标记为 PL/SQL,但因为您可能打算从普通 SQL 调用 main_xyz
,并且因为您是从 sub-functions 调用 SQL 这些循环中的上下文,data_type_1
和 table_type_1
需要在架构级别创建,而不是在 PL/SQL 中创建。 (这有 changed a bit in 12c 但不足以帮助这里)。
如果你想让它们作为 PL/SQL 类型,在包规范中声明,那么你不能从非 PL/SQL 上下文调用函数,你必须用对函数的调用替换循环,然后对 returned 集合进行迭代。
create type data_type_1 as object (x number, y number)
/
create type table_type_1 as table of data_type_1
/
create or replace package xyz AS
function main_xyz return table_type_1 pipelined;
function sub_func return table_type_1 pipelined;
function sub_func1 return table_type_1 pipelined;
end xyz;
/
create package body XYZ AS
function main_xyz return data_type_1 pipelined is
begin
--code
--pipe row(sub_func); --edit_1
FOR rec in (select * from table(sub_func1(x,y))) LOOP
pipe row(rec);
END LOOP;
end;
--function sub_func return data_type_1 pipelined is --edit_1
--begin --edit_1
--code --edit_1
--pipe row(def); --def is data_type_1 --edit_1
--end; --edit_1
function sub_func_1(x in number, y in number) return data_type_1 pipelined is
begin
--code
loop
pipe row(abc); --abc is data_type_1
end loop;
end;
end;
create package body ABC AS
function main_ABC is
begin
--code
FOR rec in (select * from table(main_xyz)) LOOP
pipe row(rec);
END LOOP;
end;
end;
我得到的错误是...
Error is showed in the block of main_xyz where sub_func1 is called.
[Error] PLS-00382 (): PLS-00382: expression is of wrong type
[Error] PLS-00306 (): PLS-00306: wrong number or types of arguments in call to
[Error] ORA-00904 (): PL/SQL: ORA-00904: : invalid identifier
[Error] PLS-00364 (): PLS-00364: loop index variable 'REC' use is invalid
上面的代码有什么问题?为什么?
您的函数正在 returning data_type_1
,并且 table 集合也在尝试使用它。但是两者都需要一个集合类型,即使您希望它们只有 return 一个值(在这种情况下没有太多点流水线)。您不能直接通过管道传输集合类型,而是通过管道传输集合的成员。所以 data_type_1
应该是标量或 object/record 类型,你需要另一种类型,它是这些的集合。
create type data_type_1 as object (x number, y number)
/
create type table_type_1 as table of data_type_1
/
create or replace package xyz AS
function main_xyz return table_type_1 pipelined;
function sub_func return table_type_1 pipelined;
function sub_func1 return table_type_1 pipelined;
end xyz;
/
create or replace package body xyz as
function main_xyz return table_type_1 pipelined is
begin
--code
for rec in (select * from table(sub_func)) loop
pipe row(data_type_1(rec.x, rec.y));
end loop;
for rec in (select * from table(sub_func1)) loop
pipe row(data_type_1(rec.x, rec.y));
end loop;
end;
function sub_func return table_type_1 pipelined is
def data_type_1;
begin
--code
pipe row(def); --def is data_type_1
end sub_func;
function sub_func1 return table_type_1 pipelined is
abc data_type_1;
begin
--code
loop
pipe row (abc); --abc is data_type_1
end loop;
end sub_func1;
end xyz;
/
所以我添加了您现有 data_type_1
的 table 类型,并将函数定义更改为 return 类型 table。 pipe row
仍然使用 data_type_1
- 每个都是 table 类型中的一行。您的循环需要查询其游标,而不是直接调用 table()
,因此我也对其进行了更改。 pipe row(sub_func);
也需要对查询进行类似的循环。
您只将此标记为 PL/SQL,但因为您可能打算从普通 SQL 调用 main_xyz
,并且因为您是从 sub-functions 调用 SQL 这些循环中的上下文,data_type_1
和 table_type_1
需要在架构级别创建,而不是在 PL/SQL 中创建。 (这有 changed a bit in 12c 但不足以帮助这里)。
如果你想让它们作为 PL/SQL 类型,在包规范中声明,那么你不能从非 PL/SQL 上下文调用函数,你必须用对函数的调用替换循环,然后对 returned 集合进行迭代。