Oracle 11g - 如何声明记录以存储基于动态的值 SQL

Oracle 11g - How to DECLARE a RECORD to store values based on Dynamic SQL

总结

正如我的问题所述,我很想知道如何定义记录以便存储通过动态 SQL 检索到的值。我有一个 table 在 CLOB 列中存储 SQL。 END 目标是使用查询的 query_id 调用 PIPELINED 函数,即 运行。我目前的问题是不知道如何定义 TYPE 以便我可以将数据通过 PIPE 输出。我无法定义 PIPELINED 函数,因为在声明 PIPELINED 函数时它需要一个类型。在我的例子中,TYPE 将根据查询 Table.

中包含的所需查询而改变

我试过的

我已经阅读了 DBMS_SQL 的用法,我发现 DBMS_SQL 有一个功能,即 DBMS_SQL.DEFINE_COLUMN 但是它需要我明确定义列 - 除非我在这里遗漏了一些东西。再次......我不知道从动态 sql 返回的列类型......它们可以是任何东西和任何顺序。

我的问题示例

下面的代码是我的问题的最简单示例。我希望在下面的示例代码中填充的记录是 rec_cursor_query。在所有其他非动态 sql 中,它将根据 TABLE 定义或使用列名和 %TYPE 关键字显式定义。 Can't use this: rec_cursor_query employees%ROWTYPE;.

DECLARE

  /* Cursor Pointer */
  cur_Query   SYS_REFCURSOR;

  /* Store Dynamic SQL */
  q           VARCHAR2(2000);

  /* Declare Record based on Dynamic SQL */
  --rec_cursor_query  ????table%ROWTYPE;  /* I realize I can't do this... but what can I do? */

BEGIN

  /* Fake Query Below saved into q */
  q   :=    q'~SELECT 1001 AS pkey, 'Jake' AS firstname, 'Johnson' AS lastname FROM dual~';

  /* Output Query just to show query was saved */
  dbms_output.put_line(q);

  OPEN cur_Query FOR
    q;

  LOOP

    FETCH cur_Query INTO rec_cursor_query; /* Again here... I can't do this due to it not being Defined */

    EXIT WHEN cur_Query%NOTFOUND;

  END LOOP;

  CLOSE cur_Query;


END
;

很简单,这在 Oracle SQL 中是不可能的。 SQL 是强数据类型。 None这个"if it looks like a duck"废话给我们看! table() 函数只适用于 pre-defined 类型(通常是 SQL 对象),因为它需要知道投影。如果您想知道,我们不能使用 ANYDATASET 或 ANYTYPE 作为流水线函数的 return 值(PLS-00630:流水线函数必须具有受支持的集合 return 类型)。

尝试的一个选项是通过为流水线函数动态生成 SQL 类型并为调用动态生成的 SQL 的流水线函数动态生成 PL/SQL 来启动您的代码.但是随后您处于将 DDL 作为查询的一部分执行的领域,这真的很混乱。简而言之,我认为这可能有效——虽然我从未尝试过——但我会说这种方法对于在生产中使用来说太不稳定了。

另一种选择是认识到 SQL 是不适合这项工作的工具。还有其他语言本身支持反射和此类 metadata-driven 功能。使用弱引用游标将数据传递给客户端应用程序。参考游标映射到 ODBC 和 JDBC 结果集,可以即时解释投影。或者升级到 Oracle 12c,它在 DBMS_SQL 中引入了对隐式结果集的支持。 Find out more.