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' 使用无效

上面的代码有什么问题?为什么?

4

1 回答 1

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,但因为您可能打算main_xyz从普通 SQL 调用,并且因为您在这些循环中从 SQL 上下文调用子函数,data_type_1并且table_type_1需要在模式级别而不是在 PL/ 中创建子函数SQL。(这在 12c 中有所改变,但不足以在这里提供帮助)。

如果你想将它们作为 PL/SQL 类型,在包规范中声明,那么你不能从非 PL/SQL 上下文调用函数,你必须用函数调用来替换循环然后对返回的集合进行迭代。

于 2016-01-20T10:36:54.970 回答