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;
我获得的错误是......
在调用sub_func1的main_xyz块中显示错误。
[错误] PLS-00382():PLS-00382:表达式类型错误 [错误] PLS-00306():PLS-00306:调用
中的参数数量或参数类型错误 [错误] ORA-00904():PL / SQL:ORA-00904 ::无效标识符
[错误] PLS-00364():PLS-00364:循环索引变量'REC'使用无效
上面的代码有什么问题?为什么?
答案 0 :(得分:2)
您的函数正在返回data_type_1
,并且表集合也在尝试使用它。但是两者都需要一个集合类型,即使你期望它们只返回一个值(在这种情况下,没有多少点流水线)。您不能直接管道集合类型,管道集合的成员。所以data_type_1
应该是标量或对象/记录类型,你需要另一种类型的集合。
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
的表类型,并更改了函数定义以返回该表类型。 pipe row
仍然使用data_type_1
- 每个都是表格类型中的一行。你的循环需要查询其光标,而不是直接调用table()
,所以我也改变了。 pipe row(sub_func);
也需要与查询类似。
您只是将其标记为PL / SQL,但是因为您可能打算从纯SQL调用main_xyz
,并且因为您从这些循环中的SQL上下文调用子函数,data_type_1
并且table_type_1
需要在模式级别而不是在PL / SQL中创建。 (这有changed a bit in 12c但不足以帮助到这里。)
如果你想将它们作为PL / SQL类型(在包规范中声明),那么就无法从非PL / SQL上下文中调用该函数,并且你必须用一个调用来替换这些循环函数后跟迭代返回的集合。