2016-01-20 44 views
0
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

@diziaq你怎么看? – user256378

回答

1

你的函数返回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,但是因为你可能打算叫main_xyz从普通的SQL,因为你是从这些循环SQL环境中调用子功能,data_type_1table_type_1需要在被创建模式级别而不是PL/SQL。 (这有changed a bit in 12c,但不足以帮助这里)。

如果你想有他们作为PL/SQL类型,在包规范中声明,那么你可以不叫从非PL/SQL方面的功能,你就必须更换一个环调用函数,然后对返回的集合进行迭代。

+0

是的我已经实现了你所描述的方式,尽管如此,我得到的错误.. – user256378

+0

@ user256378 - 我错过了循环语法中的一些括号;他们必须是模式级别的类型才能在这些游标循环中使用它们;我没有正确引用'rec'字段。至少用更新的东西进行编译。 –

+0

我再次编辑了我的问题。 – user256378