从打包函数返回集合以在 select 中使用

发布于 2024-12-12 05:21:57 字数 766 浏览 0 评论 0原文

我目前正在使用这段代码从我的函数返回行的集合。

--Source: http://www.adp-gmbh.ch/ora/plsql/coll/return_table.html

create or replace type t_col as object (
i number,
n varchar2(30)
);
/
create or replace type t_nested_table as table of t_col;
/
create or replace function return_table return t_nested_table as
  v_ret   t_nested_table;
begin
  v_ret  := t_nested_table();

  v_ret.extend;
  v_ret(v_ret.count) := t_col(1, 'one');

  v_ret.extend;
  v_ret(v_ret.count) := t_col(2, 'two');

  v_ret.extend;
  v_ret(v_ret.count) := t_col(3, 'three');

  return v_ret;
end return_table;
/

我通过发出 SQL 来调用

select * from table(return_table);

对象类型不能在包中定义,我尝试使用有效的记录类型(在 PL/SQL 中),但我无法以与此处相同的方式从中进行选择。

如何使用包内的函数实现此结果?

I'm currently using this block of code to return a collection of rows from my function.

--Source: http://www.adp-gmbh.ch/ora/plsql/coll/return_table.html

create or replace type t_col as object (
i number,
n varchar2(30)
);
/
create or replace type t_nested_table as table of t_col;
/
create or replace function return_table return t_nested_table as
  v_ret   t_nested_table;
begin
  v_ret  := t_nested_table();

  v_ret.extend;
  v_ret(v_ret.count) := t_col(1, 'one');

  v_ret.extend;
  v_ret(v_ret.count) := t_col(2, 'two');

  v_ret.extend;
  v_ret(v_ret.count) := t_col(3, 'three');

  return v_ret;
end return_table;
/

Which I call by issuing SQL

select * from table(return_table);

Object types can not be defined in a package, I tried using the record type which worked (in PL/SQL) but I couldn't select from it in the same way as I can here.

How do I achieve this result using a function inside a package?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡笑忘祈一世凡恋 2024-12-19 05:21:57

您可以在包内使用 SQL 对象,也可以使用管道函数(使用 10gr2 进行测试)。使用 SQL 对象很简单,您的实际函数可以按原样在包内使用。

以下是如何使用具有 RECORD 类型的管道函数:

SQL> CREATE OR REPLACE PACKAGE my_pkg IS
  2     TYPE t_col IS RECORD(
  3        i NUMBER,
  4        n VARCHAR2(30));
  5     TYPE t_nested_table IS TABLE OF t_col;
  6     FUNCTION return_table RETURN t_nested_table PIPELINED;
  7  END my_pkg;
  8  /

Package created
SQL> CREATE OR REPLACE PACKAGE BODY my_pkg IS
  2     FUNCTION return_table RETURN t_nested_table PIPELINED IS
  3        l_row t_col;
  4     BEGIN
  5        l_row.i := 1;
  6        l_row.n := 'one';
  7        PIPE ROW(l_row);
  8        l_row.i := 2;
  9        l_row.n := 'two';
 10        PIPE ROW(l_row);
 11        RETURN;
 12     END;
 13  END my_pkg;
 14  /

Package body created

SQL> select * from table(my_pkg.return_table);

         I N
---------- ------------------------------
         1 one
         2 two

幕后发生的事情是 Oracle 知道,由于您想在查询中使用函数(由于 PIPELINED 关键字),因此您将需要 SQL 对象,因此这些对象是在幕后为您创建的:

SQL> select object_name
  2    from user_objects o
  3   where o.created > sysdate - 1
  4     and object_type = 'TYPE';

OBJECT_NAME
--------------------------------------------------------------------------------
SYS_PLSQL_798806_24_1
SYS_PLSQL_798806_DUMMY_1
SYS_PLSQL_798806_9_1

SQL> select text from user_source where name='SYS_PLSQL_798806_9_1';

TEXT
--------------------------------------------------------------------------------
type        SYS_PLSQL_798806_9_1 as object (I NUMBER,
N VARCHAR2(30));

You could either use SQL objects inside your package or use pipelined functions (tested with 10gr2). Using SQL objects is straightforward, your actual function could be used as is inside a package.

Here's how you could use a pipelined function with a RECORD type:

SQL> CREATE OR REPLACE PACKAGE my_pkg IS
  2     TYPE t_col IS RECORD(
  3        i NUMBER,
  4        n VARCHAR2(30));
  5     TYPE t_nested_table IS TABLE OF t_col;
  6     FUNCTION return_table RETURN t_nested_table PIPELINED;
  7  END my_pkg;
  8  /

Package created
SQL> CREATE OR REPLACE PACKAGE BODY my_pkg IS
  2     FUNCTION return_table RETURN t_nested_table PIPELINED IS
  3        l_row t_col;
  4     BEGIN
  5        l_row.i := 1;
  6        l_row.n := 'one';
  7        PIPE ROW(l_row);
  8        l_row.i := 2;
  9        l_row.n := 'two';
 10        PIPE ROW(l_row);
 11        RETURN;
 12     END;
 13  END my_pkg;
 14  /

Package body created

SQL> select * from table(my_pkg.return_table);

         I N
---------- ------------------------------
         1 one
         2 two

What happens behind the scene is that Oracle understands that since you want to use your function in a query (because of the PIPELINED keyword), you will need SQL objects, so those objects are created behind the scene for you:

SQL> select object_name
  2    from user_objects o
  3   where o.created > sysdate - 1
  4     and object_type = 'TYPE';

OBJECT_NAME
--------------------------------------------------------------------------------
SYS_PLSQL_798806_24_1
SYS_PLSQL_798806_DUMMY_1
SYS_PLSQL_798806_9_1

SQL> select text from user_source where name='SYS_PLSQL_798806_9_1';

TEXT
--------------------------------------------------------------------------------
type        SYS_PLSQL_798806_9_1 as object (I NUMBER,
N VARCHAR2(30));
吃素的狼 2024-12-19 05:21:57
create or replace type t_col as object (
  i number,
  n varchar2(30)
);
/

create or replace package foo as
  type t_nested_table is table of t_col;
  function return_table return t_nested_table pipelined;
end;
/
show errors

create or replace package body foo as
  data t_nested_table := t_nested_table(t_col(1, 'one'),
                                        t_col(2, 'two'),
                                        t_col(3, 'three'));

  function return_table return t_nested_table pipelined as
  begin
    for i in data.first .. data.last loop
      pipe row(data(i));
    end loop;
    return;
  end;
end;
/
show errors

column n format a10
select * from table(foo.return_table);

         I N
---------- ----------
         1 one
         2 two
         3 three
create or replace type t_col as object (
  i number,
  n varchar2(30)
);
/

create or replace package foo as
  type t_nested_table is table of t_col;
  function return_table return t_nested_table pipelined;
end;
/
show errors

create or replace package body foo as
  data t_nested_table := t_nested_table(t_col(1, 'one'),
                                        t_col(2, 'two'),
                                        t_col(3, 'three'));

  function return_table return t_nested_table pipelined as
  begin
    for i in data.first .. data.last loop
      pipe row(data(i));
    end loop;
    return;
  end;
end;
/
show errors

column n format a10
select * from table(foo.return_table);

         I N
---------- ----------
         1 one
         2 two
         3 three
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文