将WMSYS.WM_CONCAT与Oracle XE 10g一起使用

将WMSYS.WM_CONCAT与Oracle XE 10g一起使用,oracle,oracle10g,oracle-xe,ora-00904,wm-concat,Oracle,Oracle10g,Oracle Xe,Ora 00904,Wm Concat,当我尝试将WMSYS.WM_CONCAT与Oracle XE 10g一起使用时,收到一个编译错误:ORA-00904:WMSYS.WM_CONCAT:无效标识符。有人能证实这确实是由于XE缺少这种未记录的特性造成的吗?如果是这样的话,在XE中是否还可以启用它?我已经找到了几个参考站点,但没有幸运地启用它。最后我编写了自己的函数来处理连接 CREATE or replace FUNCTION CONCAT_LIST( cur SYS_REFCURSOR, sep Varchar2 ) RETURN

当我尝试将WMSYS.WM_CONCAT与Oracle XE 10g一起使用时,收到一个编译错误:ORA-00904:WMSYS.WM_CONCAT:无效标识符。有人能证实这确实是由于XE缺少这种未记录的特性造成的吗?如果是这样的话,在XE中是否还可以启用它?

我已经找到了几个参考站点,但没有幸运地启用它。最后我编写了自己的函数来处理连接

CREATE or replace FUNCTION CONCAT_LIST( cur SYS_REFCURSOR, sep Varchar2 ) RETURN  VARCHAR2 IS
ret VARCHAR2(32000);
tmp VARCHAR2(4000);
BEGIN
loop
  fetch cur into tmp;
  exit when cur%NOTFOUND;
    if ret is null then
       ret := tmp;
    else
      ret := ret || sep || tmp;
    end if;

end loop;
RETURN ret; END;/
那么它可以被称为

选择不同的目录游标或从test_table1中选择id,,“test_table1 FROM dual”

源:

只需自己创建此函数:

CREATE OR REPLACE TYPE wm_concat_impl
   AUTHID CURRENT_USER
AS OBJECT (
   curr_str   VARCHAR2 (32767),
   STATIC FUNCTION odciaggregateinitialize (sctx IN OUT wm_concat_impl)
      RETURN NUMBER,
   MEMBER FUNCTION odciaggregateiterate (
      SELF   IN OUT   wm_concat_impl,
      p1     IN       VARCHAR2
   )
      RETURN NUMBER,
   MEMBER FUNCTION odciaggregateterminate (
      SELF          IN       wm_concat_impl,
      returnvalue   OUT      VARCHAR2,
      flags         IN       NUMBER
   )
      RETURN NUMBER,
   MEMBER FUNCTION odciaggregatemerge (
      SELF    IN OUT   wm_concat_impl,
      sctx2   IN       wm_concat_impl
   )
      RETURN NUMBER
);
/

CREATE OR REPLACE TYPE BODY wm_concat_impl
IS
   STATIC FUNCTION odciaggregateinitialize (sctx IN OUT wm_concat_impl)
      RETURN NUMBER
   IS
   BEGIN
      sctx := wm_concat_impl (NULL);
      RETURN odciconst.success;
   END;
   MEMBER FUNCTION odciaggregateiterate (
      SELF   IN OUT   wm_concat_impl,
      p1     IN       VARCHAR2
   )
      RETURN NUMBER
   IS
   BEGIN
      IF (curr_str IS NOT NULL)
      THEN
         curr_str := curr_str || ',' || p1;
      ELSE
         curr_str := p1;
      END IF;

      RETURN odciconst.success;
   END;
   MEMBER FUNCTION odciaggregateterminate (
      SELF          IN       wm_concat_impl,
      returnvalue   OUT      VARCHAR2,
      flags         IN       NUMBER
   )
      RETURN NUMBER
   IS
   BEGIN
      returnvalue := curr_str;
      RETURN odciconst.success;
   END;
   MEMBER FUNCTION odciaggregatemerge (
      SELF    IN OUT   wm_concat_impl,
      sctx2   IN       wm_concat_impl
   )
      RETURN NUMBER
   IS
   BEGIN
      IF (sctx2.curr_str IS NOT NULL)
      THEN
         SELF.curr_str := SELF.curr_str || ',' || sctx2.curr_str;
      END IF;

      RETURN odciconst.success;
   END;
END;
/

CREATE OR REPLACE FUNCTION wm_concat (p1 VARCHAR2)
   RETURN VARCHAR2
   AGGREGATE USING wm_concat_impl;
/

建议不要使用WM_CONCAT,因为它是一个未记录的功能,并且已从12c版本中删除。看

如果您在11gR2及以上,请使用LISTAGG

对于11g之前不支持Listag的版本,您可以使用ROW\ U NUMBER和SYS\ U CONNECT\ U BY\ U PATH函数

比如说,

SELECT deptno,
       LTRIM(MAX(SYS_CONNECT_BY_PATH(ename,','))
       KEEP (DENSE_RANK LAST ORDER BY curr),',') AS employees
FROM   (SELECT deptno,
               ename,
               ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY ename) AS curr,
               ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY ename) -1 AS prev
        FROM   emp)
GROUP BY deptno
CONNECT BY prev = PRIOR curr AND deptno = PRIOR deptno
START WITH curr = 1;

    DEPTNO EMPLOYEES
---------- --------------------------------------------------
        10 CLARK,KING,MILLER
        20 ADAMS,FORD,JONES,SCOTT,SMITH
        30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD

3 rows selected.

谢谢,我真的很好奇这个功能是否可以启用。我找到的最佳替代方法是此处的用户定义聚合函数:。我将函数从string_agg重命名为wm_concat,从那时起,我可以与拥有完整oracle 10g的同事共享存储过程。本文中给出的方法允许使用与真正的wm_concat相同的语法-只要您不使用完全符合wm_concat与wm_syst的脚本,这是非常巧妙的。我有几个大的查询,我正在使用这个函数。一旦我回到办公室,我将创建一个新的,并检查性能。这让我好奇。谢谢很酷,我很想在您完成后听到您的性能结果。我对CONCAT_LIST和STRING_AGG这两个函数进行了一些负载测试,发现我必须对我的函数进行一次修改。我忘了关上光标,很快就把允许的金额最大化了。在做了更改之后,我创建了一个查询,将一组250家店铺分组为它们相应的类型。CONCAT_列表用2.68秒完成,oracle base的字符串_AGG用0.38秒完成,看起来干净多了。我已经改变了我必须引用这个新函数的几个查询。在这里,我以为我可以帮助你,而你最终帮助了我。谢谢