流水线函数调用另一个流水线函数
这是一个包含两个管道函数的包:
create or replace type tq84_line as table of varchar2(25);
/
create or replace package tq84_pipelined as
function more_rows return tq84_line pipelined;
function go return tq84_line pipelined;
end tq84_pipelined;
/
Ant 相应的包主体:
create or replace package body tq84_pipelined as
function more_rows return tq84_line pipelined is
begin
pipe row('ist');
pipe row('Eugen,');
return;
end more_rows;
function go return tq84_line pipelined is
begin
pipe row('Mein');
pipe row('Name');
/* start */
for next in (
select column_value line from table(more_rows)
)
loop
pipe row(next.line);
end loop;
/* end */
pipe row('ich');
pipe row('weiss');
pipe row('von');
pipe row('nichts.');
end go;
end tq84_pipelined;
/
重要的是 go 某种程度 使用 for next in ...< 调用
more_rows
/code> /* start */
和 /* end */
我可以按如下方式使用该包:
select * from table(tq84_pipelined.go);
这一切都很好,但我希望我可以替换通过简单调用 more_rows
即可显示 /* start */
和 /* end */
之间的行。
然而,这显然是不可能的,因为它生成了PLS-00221:'MORE_ROWS'不是一个过程或未定义。
所以,我的问题是:真的没有办法缩短循环吗?
编辑
显然,从到目前为止的答案来看,我的问题尚不清楚。
如上所述,该软件包有效。
但我对标记 /* start */
和 /* end */
之间的 6 行(即:六行)感到困扰。我想用一行替换它们。但我还没有找到任何方法做到这一点。
Here's a package with two pipelined functions:
create or replace type tq84_line as table of varchar2(25);
/
create or replace package tq84_pipelined as
function more_rows return tq84_line pipelined;
function go return tq84_line pipelined;
end tq84_pipelined;
/
Ant the corresponding package body:
create or replace package body tq84_pipelined as
function more_rows return tq84_line pipelined is
begin
pipe row('ist');
pipe row('Eugen,');
return;
end more_rows;
function go return tq84_line pipelined is
begin
pipe row('Mein');
pipe row('Name');
/* start */
for next in (
select column_value line from table(more_rows)
)
loop
pipe row(next.line);
end loop;
/* end */
pipe row('ich');
pipe row('weiss');
pipe row('von');
pipe row('nichts.');
end go;
end tq84_pipelined;
/
The important thing is that go sort of calls more_rows
with the for next in ...
between /* start */
and /* end */
I can use the package as follows:
select * from table(tq84_pipelined.go);
This is all fine and dandy, but I hoped I could replace the lines between /* start */
and /* end */
with a simple call of more_rows
.
However, this is obviously not possible, as it generetes a PLS-00221: 'MORE_ROWS' is not a procedure or is undefined.
So, my question: is there really no way to shortcut the loop?
EDIT
Obviously, from the answers so far, my question was not clear.
The package, as stated works.
But I am bothered with the 6 (that is: SIX) lines between the markers /* start */
and /* end */
. I'd like to replace these with one single line. But I havent found any way doing that.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
管道函数的要点是提供 TABLE() 函数。我认为没有任何办法可以避免它。不幸的是,我们必须将其输出分配给 PL/SQL 变量。我们无法将管道函数分配给像这样的
nt := more_rows;
嵌套表,因为它必须是
SELECT ... FROM TABLE()
。我有一个稍微不同的解决方案供您考虑。不知道是否能解决你的根本问题。
我确信您已经知道(但为了其他搜索者的利益),Oracle 10g 中引入了用于将集合组合在一起的 MULTISET UNION 语法。
此版本的 GO() 产生与原始实现相同的输出:
The point of pipelined functions is to feed TABLE() functions. I don't think there is any way to avoid it. Unfortunately we have to assign its output to a PL/SQL variable. We can't assign a pipelined function to a nested table like this
nt := more_rows;
due toSo
SELECT ... FROM TABLE()
it has to be.I have a slightly different solution for your consideration. I don't know whether it solves your underlying problem.
As I'm sure you're aware (but for the benefit of other seekers) the MULTISET UNION syntax for glomming collections together was introduced in Oracle 10g.
This version of GO() produces the same output as your original implementation:
尝试
从表中选择column_value行(tq84_line.more_rows)
即在查询中包含包名称。
Try
select column_value line from table(tq84_line.more_rows)
i.e. include the package name in the query.