从过程中的函数返回结果集

时间:2016-09-02 20:36:13

标签: oracle plsql

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的非流水线模拟:

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

似乎PL / SQL中不允许使用表函数 - 与流水线无关。

如果是这样,有没有其他方法可以采取动态查询,结果模式可以是什么,并将其作为'with'输入提供给后续静态查询,所有这些都在PL / SQL过程中?< / p>

1 个答案:

答案 0 :(得分:0)

我不相信这可以做到,因为看起来有一组非固定列作为PL / SQL代码的一部分(作为CTE输入或其他类似方法)不允许代码预先-compiled。似乎唯一的答案是保持整个过程的动态。

我很难回答我自己的问题,但是当我得出这个结论时,我不想让它保持开放,并且删除这个问题可能会很糟糕,因为其他人可能会在将来尝试这样做...