Oracle WM_CONCAT与DISTINCT子句-编译包与独立查询问题
我在写一些使用WM_CONCAT函数的程序。运行此查询时:Oracle WM_CONCAT与DISTINCT子句-编译包与独立查询问题,oracle,plsql,oracle10g,oracle-sqldeveloper,Oracle,Plsql,Oracle10g,Oracle Sqldeveloper,我在写一些使用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 V
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没有得到官方支持,但有人能解释一下为什么它可以作为一个独立的查询使用,但不能在包中编译吗?问题是WM_CONCAT是在pl/sql上编写的存储过程 有一个开放的bug 9323679:PL/SQL调用用户定义的aggregate函数,该函数与ORA-30482不同 解决此类问题的方法是使用动态sql 因此,如果您将查询封装在
EXECUTE IMMEDIATE '<your_query>';
那么它应该会起作用
但是正如OldProgrammer已经建议的那样,您最好避免使用这个WM_CONCAT。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;
您应该能够使用LISTAGG函数获得类似的结果。我将其标记为oracle10g,它不提供该函数。我意识到pl/sql解析器与查询解析器不同,但我真正想知道的是它发生的原因,即导致这种行为的规则是什么。可能有一个很好的理由,在pl/sql的某些特定场景中不允许使用DISTINCT,我这里的示例是其中的一个子集示例,不能代表“问题”的整体。您能提供一个到描述此行为的文档的链接吗?@Reimus抱歉,似乎我有点把这个问题与新的11g行为混淆了。我正在修正这个答案。啊,所以这是一个bug,不是因为一些功能需求。谢谢你的参考资料。我没有权限访问他们的追踪器,但我能够找到更多与bug编号相关的帖子。