ORACLE PL/SQL:使用集合的动态 SQL 选择

Posted

技术标签:

【中文标题】ORACLE PL/SQL:使用集合的动态 SQL 选择【英文标题】:ORACLE PL/SQL: Dynamic SQL Select using a Collection 【发布时间】:2011-03-08 15:57:55 【问题描述】:

是否可以创建从现有集合中提取的动态 SQL 语句?

l_collection := pack.get_items(
                i_code => get_items_list.i_code ,
                i_name => get_items_list.i_name );

现在,假设我想使用动态 SQL 从该集合中选择一个 COUNT。那可能吗?此外,我还想从该集合中进行子选择。

【问题讨论】:

【参考方案1】:

如果集合类型是在模式级别声明的,则它可以在 SQL 语句中使用,包括动态语句。您需要将其显式转换为正确的集合类型,否则 SQL 引擎不知道它是什么类型。

EXECUTE IMMEDIATE
  'SELECT COUNT(*) FROM TABLE(CAST(:collection AS collection_type))'
   INTO l_count
   USING l_collection
  ;

我不确定您是否还有其他原因要使用动态 SQL,或者您是否只是假设在这种情况下有必要。如果您只想选择计数,则没有必要。这个内联 SQL 应该可以正常工作:

SELECT COUNT(*) INTO l_count FROM TABLE(CAST(l_collection AS collection_type));

当然,如果这就是你想要的,你根本不需要 SQL,只需要l_count := l_collection.COUNT

编辑——添加完整的示例

CREATE OR REPLACE TYPE testtype AS OBJECT( x NUMBER, y NUMBER);
/

CREATE OR REPLACE TYPE testtypetab AS TABLE OF testtype;
/

DECLARE
  t  testtypetab := testtypetab();
  l_count integer;
BEGIN
  -- Populate the collection with some data
  SELECT testtype(LEVEL, LEVEL) BULK COLLECT INTO t FROM dual CONNECT BY LEVEL<21;

  -- Show that we can query it using inline SQL
  SELECT count(*) INTO l_count FROM TABLE(CAST(t AS testtypetab));
  dbms_output.put_line( l_count );

  -- Clear the collection
  t.DELETE;

  -- Show that we can query it using dynamic SQL
  EXECUTE IMMEDIATE 'select count(*) from table(cast(:collection as testtypetab))'
    into l_count using t;
  dbms_output.put_line( l_count );
END;
/

【讨论】:

嗯...似乎不起作用。一直给我一个表达式是错误类型的错误。 我添加了一个更完整的示例,它可以为我成功运行。似乎“表达式的类型错误”通常意味着您试图将对象分配给非对象变量,反之亦然。如果您仍然遇到问题,也许您应该发布一个小代码示例来显示您的具体问题。 是的,我的 SQL Developer 安装有些问题。即使我删除了代码,我也会收到此错误。 我只是在没有调试的情况下运行它,它正在输出数据。看起来可行,非常感谢。 SQL Developer 无法轻松映射数据类型时会出现问题。如果您添加适当的 CAST(....) 它通常会消除“表达式类型错误”错误

以上是关于ORACLE PL/SQL:使用集合的动态 SQL 选择的主要内容,如果未能解决你的问题,请参考以下文章

Oracle:使用 SQL 或 PL/SQL 查找动态 SQL 中的错误位置

使用嵌套表在 Oracle PL/SQL 中构建动态 SQL

如何在 Oracle 中调试 PL/SQL 集合的值?

如何使用 Oracle (PL/SQL) 动态 sql 将数据查询到 %rowtype 变量中

Oracle PL/SQL - 循环值作为没有动态 SQL 的动态列名

Oracle_PL/SQL 动态sql