PL / SQL:你能否从流水线函数传递返回的数据?

时间:2014-04-23 12:05:43

标签: sql plsql

我在数据库包中有一个函数,它返回一个流水线对象集合。我希望概括该功能,以便可以根据不同的数据调用相同的功能。但是,我希望保留现有的兼容性功能。有没有办法在不循环行的情况下传递管道?

一个让它更清晰的例子。我有一个函数foo:

FUNCTION foo(some_id in varchar2) return mypackage.mytype pipelined is
   arFoo  mypackage.mytype;
BEGIN
  -- do stuff to fill data in arFoo based on some_id
  for i in nvl(arFoo.first,0) .. nvl(arFoo.last, -1) loop
     pipe row(arFoo(i));
  end loop;
  return;
END;

我将创建一个功能栏

FUNCTION bar(arData in myParamType) return return mypackage.mytype pipelined is
   arFoo  mypackage.mytype;
BEGIN
  -- do stuff to fill data in arFoo based on data in arData
  for i in nvl(arFoo.first,0) .. nvl(arFoo.last, -1) loop
     pipe row(arFoo(i));
  end loop;
  return;
END;

我会喜欢以下列方式保留foo:

FUNCTION foo(some_id in varchar2) return mypackage.mytype pipelined is
   arData  myParamType;
BEGIN
  -- do stuff to fill data in arData  based on some_id
  return arBar(arData);
END;

但是,return arBar(arData);是不允许的 - 流水线函数本身必须有return作为staement。问题是如何将bar返回的管道连接到foo返回的管道。我能看到的唯一方法是循环结果并再次管道:

for r in (select * from table(bar(arData))) loop
   pipe row(r);
end loop;
但是,这让我感到特别低效。有没有更有效的方法将bar中的管道连接到foo中的管道而不进行循环?

1 个答案:

答案 0 :(得分:0)

我将此作为一个aswer提交,因为它是我解决它的方式。它在某些方面只是部分答案,因为我找不到使用流水线功能的好方法。我所做的是将返回对象创建为全局用户定义的对象(而不是包规范中的记录类型),然后直接返回对象。

换句话说,我定义了这样的函数:

FUNCTION bar(arData in myParamType) return mytype is
   arFoo  mytype;
BEGIN
  -- do stuff to fill data in arFoo based on data in arData
  return arFoo;
END;

FUNCTION foo(some_id in varchar2) return mytype is
   arData  myParamType;
BEGIN
  -- do stuff to fill data in arData  based on some_id
  return arBar(arData);
END;

并删除以下内容(已在mypackage规范中)

type mytype is record(
   foo_id    foo.id%type
)

而是运行脚本来创建全局类型

create or replace type mytype as object(
   foo_id    number(5,0)
)

这意味着当我的新内部函数存在时,函数(select * from table(foo('x'))上的变体)的使用保持不变,并且可以在其他情况下直接调用。

在包规范中定义类型会更简洁,但我们已经有了一些全局对象,所以我们可以处理它。 (我认为 oracle内部定义了全局对象来处理流水线函数)。不幸的是,我们不能在全局对象定义中使用%type,但我们可以接受它。