2011-10-25 9 views
2

私は現在、このコードブロックを使用して、自分の関数から行のコレクションを返します。私はselectで使用するパッケージ関数からのコレクションを返します

select * from table(return_table); 

オブジェクトタイプがパッケージで定義することはできませんSQLを発行することで呼び出す

--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; 
/

は、私は(PL/SQLで)働いていたレコードタイプを使用してみましたが、私は選択ができませんでした私がここにいるのと同じ方法でそれから。

パッケージ内の関数を使用してこの結果を達成するにはどうすればよいですか?

答えて

6

パッケージ内で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)); 
+0

答えてくれてありがとう、あなたは彼らはまだ「あなたのパッケージ内のSQLオブジェクトを使用する」と言うとき、パッケージの外で定義する必要がありますか?私はパッケージ内にオブジェクトを定義しようとしましたが、 "PLS-00540:このコンテキストではサポートされていないオブジェクトです"。私は、使用したパッケージ内にすべての型定義を保持しようとしたかったのです。 – TownCube

+0

はいSQLオブジェクトは常にパッケージ外で定義されます。パッケージ内で定義されたPLSQLレコード・タイプにはSQLからアクセスできません。 SELECTからテーブル・オブジェクトを照会する場合は、SQLオブジェクト(パッケージ外のタイプとして定義)が必要です。私は個人的には、むしろ、Oracleによって選択された任意の名前よりも、一貫して名前のついたSQLオブジェクトを自分自身のために使うつもりです。 –

0
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 
関連する問題