Oracle 从打包函数返回集合以在select中使用
我目前正在使用这段代码从函数返回一组行Oracle 从打包函数返回集合以在select中使用,oracle,plsql,Oracle,Plsql,我目前正在使用这段代码从函数返回一组行 --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
--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中),但无法以与此处相同的方式从中进行选择
如何使用包中的函数实现此结果?您可以在包中使用SQL对象,也可以使用流水线函数(使用10gr2测试)。使用SQL对象非常简单,您的实际函数可以像在包中一样使用 以下是如何将流水线函数与记录类型一起使用:
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));
感谢您的回答,当您说“在包内使用SQL对象”时,它们仍然需要在包外定义,对吗?我试图在一个包中定义一个对象,结果得到“PLS-00540:此上下文中不支持对象”。我想尝试将我所有的类型定义都保存在使用过的包内。是的,SQL对象总是在包外定义。无法从SQL访问包中定义的PLSQL记录类型。如果要从SELECT查询表对象,则需要SQL对象(定义为包外部的类型)。我个人更愿意选择一个统一命名的SQL对象,而不是Oracle选择的任意名称。
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