2017-05-16 12 views
-1

ローカルに定義されたテーブルタイプを、別のローカルに定義されたテーブルタイプを返すパイプライン関数である関数に渡す必要があります。ここでPLSQLローカルコレクションをパイプライン関数に渡す

はサンプルデータです:

create table my_tab 
(i NUMBER, 
n VARCHAR2(30)); 

insert into my_tab values (1, 'Peter'); 
insert into my_tab values (2, 'Dakshesh'); 
insert into my_tab values (1, 'Maggie'); 
insert into my_tab values (3, 'Madhu'); 
commit; 

私のコードは次のとおりです。

CREATE OR REPLACE PACKAGE my_pkg IS 
    TYPE t_col IS RECORD(
    i NUMBER, 
    n VARCHAR2(30)); 
    TYPE t_nested_table IS TABLE OF t_col; 
    TYPE t_number IS TABLE OF NUMBER; 
    FUNCTION iterate_table RETURN t_number PIPELINED; 
    FUNCTION return_table(in_t_num t_number) RETURN t_nested_table PIPELINED; 
    g_number t_number ; 
    g_nested_number t_nested_table ; 
    END my_pkg; 
/

ボディ:私は同じようにそれを呼び出すようにしようとすると

CREATE OR REPLACE PACKAGE BODY my_pkg IS 
    FUNCTION iterate_table RETURN t_number PIPELINED IS 
    BEGIN 
     IF ((g_number IS NOT NULL) AND (g_number.EXISTS (1))) 
     THEN 
     FOR i IN 1 .. g_number.COUNT 
     LOOP 
      IF g_number (i) IS NOT NULL 
      THEN 
       PIPE ROW (g_number (i)); 
      END IF; 
     END LOOP; 
     END IF; 
     RETURN; 
    EXCEPTION 
     WHEN OTHERS 
     THEN 
     RAISE; 
    END iterate_table; 

    FUNCTION return_table(in_t_num t_number) RETURN t_nested_table PIPELINED IS 
     l_row t_nested_table ; 
     CURSOR cur_test IS 
      select mt.i, mt.n 
      from my_tab mt, TABLE(iterate_table) tab 
      where mt.i = tab.column_value; 
    BEGIN 
     OPEN cur_test; 
     FETCH cur_test BULK COLLECT into l_row; 
     CLOSE cur_test; 
     FOR i IN 1..l_row.COUNT 
     LOOP 
      PIPE ROW(l_row(i)); 
     END LOOP; 
     RETURN; 
    END return_table; 
END my_pkg; 
/

今、このコードは、正常にコンパイルパイプライン関数、エラーを返す-

select * from table(my_pkg.return_table(my_pkg.t_number(1))); 

エラー - ORA-00902: invalid datatype 00902. 00000 - "invalid datatype" *Cause:
*Action: Error at Line: 14 Column: 41

このコードのための2つの前提条件である -

  1. コレクションは、すべてのローカルに定義されなければなりません。

  2. この関数はパイプライン化する必要があります。

ヘルプ!!

テーブルとその単一テーブルでエラーが発生しないため、外部キー制約が保持されません。

+0

[OracleのORA-00902無効なデータ型エラー]の可能な重複に(http://stackoverflow.com/questions/24978942/oracle-ora-00902-invalid-datatype-error) –

+0

いない...それはさ別の....私はテーブルを作成している間に任意のエラーを取得していないと単一のテーブルだけ..制約の違反。 –

+0

もあります。匿名ブロックとdbms_outputユーティリティを使用して印刷すると、出力を取得できます。 –

答えて

1

oracle 11では不可能です。なぜoracleが「無効なデータ型」をスローするのかわかりません。 このクエリを匿名ブロックに入れると、PLS-00642: Local Collection Types Not Allowed in SQL Statement

となり、SQLレベルのコレクションを作成することはできません。ソリューションは事前定義された型を使用しています。あらかじめ定義されたコレクションの良いソースはOracle Data Cartridgeです。すべてt_numberODCINumberListに置き換えてください。 Oracleの10と11では

predefined collections

+0

sys所有オブジェクトは使用できません。 –

0

、PL/SQLスコープで定義されているSQLスコープでコレクションを使用することはできません。 In Oracle 12、あなたがしようとしているものはうまくいくはずです。

これを実行する場合は、SQLスコープ(パッケージ内ではない)で型を宣言します。

CREATE OR REPLACE TYPE t_col IS OBJECT(
    i NUMBER, 
    n VARCHAR2(30) 
); 
/

CREATE OR REPLACE TYPE t_nested_table IS TABLE OF t_col; 
/

CREATE OR REPLACE TYPE t_number IS TABLE OF NUMBER; 
/

CREATE OR REPLACE PACKAGE my_pkg IS 
    FUNCTION iterate_table RETURN t_number PIPELINED; 
    FUNCTION return_table(in_t_num t_number) RETURN t_nested_table PIPELINED; 
    g_number t_number ; 
    g_nested_number t_nested_table ; 
END my_pkg; 
/
+0

パッケージの外にタイプを作成したくない...... !!!! –

+0

と私はオラクル12を使用しています... –

+0

@ ShrutiJoshiあなたの質問では役に立ちましたと言いました。私は、バージョンを含めるために質問にタグを付け直しました。 – MT0