2016-09-02 27 views
1

this questionとよく似ていますが、私は関数から結果セットを返し、通常のテーブルのようにこの結果セットを使用しますが、プロシージャ内からこれをやりたいOracleバージョン> = 11を使用します)。プロシージャ内の関数から結果を返す

私の基本的な目的は、非常に複雑な静的SQL文の開始点として動的クエリの結果を使用できるようにすることです。

SQL * PLUSプロンプトからの直接呼び出しでは、複数のソリューションが存在しますが、プロシージャで実行するとすべてが失敗するようです。たとえば、「method4」を使用して:私の実際のアプリケーションで

SQL> WITH q AS (SELECT * FROM TABLE(method4.query('select id, pid from 
    2 my_table where rownum < 100'))) 
    3 SELECT * FROM q where rownum <4; 

      ID  PID 
--------------- ---------- 
      72  499 
      11   89 
      13   23 

3 rows selected. 

SQL> CREATE OR REPLACE PROCEDURE test_x (
    2  p_sql IN VARCHAR2, 
    3  p_results OUT SYS_REFCURSOR 
    4 ) IS 
    5  BEGIN 
    6  open p_results for 
    7  WITH q AS (SELECT * FROM TABLE(method4.query(p_sql))) 
    8  SELECT * FROM q where rownum <4; -- this is where the complex logic would go 
    9  END test_x; 
10/

Warning: Procedure created with compilation errors. 

SQL> show errors 
Errors for PROCEDURE TEST_X: 

LINE/COL ERROR 
-------- ----------------------------------------------------------------- 
7/4  PL/SQL: SQL Statement ignored 
7/29  PL/SQL: ORA-22905: cannot access rows from a non-nested table 
     item 

SQL> 

を、プロシージャ内のクエリはかなり長くて複雑になります。私は各呼び出しの動的SQLの生成を避けたい。

ストアドプロシージャ内から「ANYDATASETテーブル関数」を利用する方法はありますか?いいえ、これは私の現在の「フォールバック」ソリューションです。

更新: PL/SQLコンテキストでパイプライン化されたコンテンツを受け取ることはできません。これは、と思わ

SQL> CREATE OR REPLACE FUNCTION myQuery (
    2  p_1 IN VARCHAR2 
    3 ) RETURN ANYDATASET AS p_result ANYDATASET; 
    4  BEGIN 
    5    EXECUTE IMMEDIATE p_1 INTO p_result; 
    6    RETURN(p_result); 
    7 END myQuery; 
    8/

Function created. 

SQL> CREATE OR REPLACE PROCEDURE test_x2 (
    2  p_sql IN VARCHAR2, 
    3  p_results OUT SYS_REFCURSOR 
    4 ) IS 
    5  myset anydataset; 
    6  BEGIN 
    7  myset := method4.query(p_sql); 
    8  open p_results for 
    9  WITH q AS (SELECT * FROM TABLE(myset)) 
10  SELECT * FROM q where rownum <4; -- this is where the complex logic would go 
11  END test_x2; 
12/

Warning: Procedure created with compilation errors. 

SQL> show errors 
Errors for PROCEDURE TEST_X2: 

LINE/COL ERROR 
-------- ----------------------------------------------------------------- 
9/7  PL/SQL: SQL Statement ignored 
9/32  PL/SQL: ORA-22905: cannot access rows from a non-nested table 
     item 

106/13 PLS-00653: aggregate/table functions are not allowed in PL/SQL 
     scope 

は、初期SQLの以下の非パイプラインアナログを考えると...私は同じ問題を抱えていると信じて - 私は唯一の非パイプラインアプローチと私の葉と信じていますPL/SQLでは、パイプライン処理とは独立していても、テーブル・ファンクションの使用は許可されていません。

結果のスキーマが何かになる可能性のある動的問合せを取得し、PL/SQLプロシージャ内の後続の静的問合せに「入力」として入力する方法はありますか?

+0

私は関数の値を最初にいくつかの変数に代入するべきだと考えます。手続きの中で、関数が返す型の変数を宣言し、関数の結果をその変数に代入します。次に、変数を 'SELECT * FROM TABLE'ステートメントで使用します。 – AndrewMcCoist

+0

@AndrewMcCoist - 提案をいただきありがとうございますが、変数を設定した行にエラーを移動させたようです。 ( "myset:= method4.query(p_sql);"という行はORA-22905エラーを受け取ります) – anon

+0

ああ。忘れてた。あなたの 'method4.query'は' PIPELINED'関数ですか?そうであれば、PL/SQLコンテキストではこのように取得することはできません。それはあなたに通常のテーブルタイプを返さなければなりません。 – AndrewMcCoist

答えて

0

PL/SQLコードの一部として固定されていない列セットを使用すると(CTE入力または他の同様のアプローチとして)、コードが許可されていないように見えるため、あらかじめコンパイルされた唯一の答えは、手順全体を動的なものにすることです。

私は自分自身の質問に答えるのが難しいと感じますが、私はこの結論に至ったときにそれを開いたままにしたくないし、将来誰か他の人がこれをやろうとしているかもしれないので、 ..

関連する問題