2

パイプライン関数で動的クエリを実行し、このクエリの結果を返したいと考えています。これを行うことは可能ですか?パイプライン関数は、テーブルのように動作するため、アプリケーションの適切なインターフェイスを実現するのに便利です。

関数:

CREATE OR REPLACE FUNCTION MyFunction(p_schema VARCHAR2) RETURN MyTableType Pipelined IS
v_query VARCHAR2(1000);
BEGIN
  v_query := 'SELECT * FROM TABLE ('||p_schema||'.somepackage.SomeFunction)'; --SomeFunction is another pipelined function
  EXECUTE IMMEDIATE v_query;
  --Results of the v_query are compatible with MyTableType's row type. But how to return them from pipelined function?
END;
4

3 に答える 3

3

動的 SQL とパイプライン関数を組み合わせることができますが、戻り値の型は動的ではありません。返される列の数と型は固定されます。

EXECUTE IMMEDIATEwith BULK COLLECT(thanks @be here now )、動的カーソル、またはDBMS_SQL複数の行を返すために使用できます。動的カーソルの例を次に示します。

SQL> CREATE OR REPLACE PACKAGE pkg AS
  2     TYPE test_tab IS TABLE OF test%ROWTYPE;
  3     FUNCTION dynamic_cursor(l_where VARCHAR2) RETURN test_tab PIPELINED;
  4  END;
  5  /

Package created.

SQL> CREATE OR REPLACE PACKAGE BODY pkg IS
  2     FUNCTION dynamic_cursor(l_where VARCHAR2) RETURN test_tab PIPELINED IS
  3        cc sys_refcursor;
  4        l_row test%ROWTYPE;
  5     BEGIN
  6        OPEN cc FOR 'SELECT * FROM test WHERE ' || l_where;
  7        LOOP
  8           FETCH cc INTO l_row;
  9           EXIT WHEN cc%NOTFOUND;
 10           PIPE ROW (l_row);
 11        END LOOP;
 12        RETURN;
 13     END;
 14  END;
 15  /

Package body created.

この動的関数を呼び出しましょう:

SQL> SELECT *
  2    FROM TABLE(pkg.dynamic_cursor('id <= 2'));

        ID DAT
---------- ---
         1 xxx
         2 xxx

動的 SQL の場合と同様に、SQL インジェクションに注意してください。

于 2012-09-25T08:35:53.433 に答える
1

私はこのようなことを考えます:

CREATE OR REPLACE FUNCTION MyFunction(par1 VARCHAR2, ...) RETURN MyTableType Pipelined IS
v_query VARCHAR2(1000);
l_result MyTableType;
BEGIN
  v_query := --My query created based on parameters
  EXECUTE IMMEDIATE v_query into l_result;

  pipe row(l_result);
END;

v_query が 1 行を返す場合にのみ機能します。

于 2012-09-25T08:29:39.767 に答える