【问题标题】:WM_CONCAT with DISTINCT Clause - Compiled Package versus Stand-Alone Query Issue带有 DISTINCT 子句的 WM_CONCAT - 编译包与独立查询问题
【发布时间】:2013-10-24 21:43:07
【问题描述】:

我正在编写一些使用 WM_CONCAT 函数的程序。当我运行这个查询时:

SELECT WM_CONCAT(DISTINCT employee_id)
FROM   employee
WHERE  ROWNUM < 20;

它工作正常。当我尝试在包函数或过程中编译相对相同的查询时,会产生以下错误:PL/SQL: ORA-30482: DISTINCT option not allowed for this function

FUNCTION fetch_raw_data_by_range
RETURN VARCHAR2 IS

    v_some_string VARCHAR2(32000);

BEGIN

    SELECT WM_CONCAT(DISTINCT employee_id)
    INTO   v_some_string
    FROM   employee
    WHERE  ROWNUM < 20;

    RETURN v_some_string;

END;

我意识到 WM_CONCAT 不受官方支持,但有人可以解释为什么它可以作为 DISTINCT 的独立查询工作,但不能在包中编译?

【问题讨论】:

  • 使用 LISTAGG 函数应该可以得到类似的结果。
  • 我将其标记为 oracle10g,它不提供该功能

标签: oracle plsql oracle10g oracle-sqldeveloper


【解决方案1】:

问题是WM_CONCAT是写在pl/sql上的存储过程。

有一个未解决的错误 #9323679:PL/SQL CALLING A USER DEFINED AGGREGRATE FUNCTION WITH DISTINCT FAILS ORA-30482。

此类问题的解决方法是使用动态 sql。

因此,如果您将查询包装在

中
EXECUTE IMMEDIATE '<your_query>';

那么它应该可以工作了。

但正如 OldProgrammer 已经建议的那样,你最好完全避免使用这个 WM_CONCAT。

【讨论】:

  • 您能否提供一个指向描述此行为的文档的链接?
  • @Reimus 抱歉,我似乎把这个问题与新的 11g 行为混淆了。我正在修复这个答案。
  • 啊,所以这是一个错误,而不是由于某些功能要求。感谢您提供参考资料。我无法访问他们的跟踪器,但我能够找到更多与错误编号相关的帖子。
【解决方案2】:

PL/SQL 不允许您在聚合函数中使用distinct,并且此问题表明 SQL 引擎和 PL/SQL 引擎不使用相同的解析器。

解决这个问题的方法之一是使用如下子查询,

SELECT WM_CONCAT(employee_id)
INTO   v_some_string
FROM   (select DISTINCT employee_id
        FROM   employee)
WHERE  ROWNUM < 20;

另一个解决方案是按照 Nagh 的建议使用动态 SQL,

FUNCTION fetch_raw_data_by_range
RETURN VARCHAR2 IS

    v_some_string VARCHAR2(32000);
    v_sql VARCHAR2(200);

BEGIN

    v_sql :='SELECT WM_CONCAT(DISTINCT employee_id)
             FROM   employee
             WHERE  ROWNUM < 20';

    execute immediate v_sql INTO v_some_string;
    RETURN v_some_string;
END;

【讨论】:

  • 我意识到 pl/sql 解析器与查询解析器不同,但我真正想知道的是它为什么会发生,即导致这种行为的规则是什么。在 pl/sql 中的某些特定场景中不允许 DISTINCT 可能是有充分理由的,其中我的示例是一个子集示例,并不代表整个“问题”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-02
  • 1970-01-01
  • 2020-03-28
  • 2020-12-05
  • 2019-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多