WM_CONCAT字符超过4000的处理办法

 

参考网址:

http://stackoverflow.com/questions/11541383/ordering-by-list-of-strings-in-oracle-sql-without-listagg

字符串拼接技巧和方式:http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php

http://www.williamrobertson.net/documents/one-row.html

在进行使用WM_CONCAT或者自定义的聚合函数,进行拼串的时候,可能遇到拼串形成的结果集大于4000,这时候,系统会提示,超过系统限制。所以,在这个时候,最好的处理办法就是将结果集处理成CLOB格式,

下面共有两种处理方式:

1、使用函数

类型:

1 create or replace type str2tblType as table of varchar2(4000)

函数:

CREATE OR REPLACE FUNCTION tab2clob(p_str2tbltype str2tbltype,

                    p_delim       IN VARCHAR2 DEFAULT ',') RETURN CLOB IS

    l_result CLOB;

  BEGIN

    FOR cc IN (SELECT column_value

                 FROM TABLE(p_str2tbltype)

                ORDER BY column_value) LOOP

      l_result := l_result || p_delim || cc.column_value;

    END LOOP;

    RETURN ltrim(l_result, p_delim);

  END;

  

测试:

初始化数据:

1 BEGIN2   FOR idx IN 1 .. 10000 LOOP

3     INSERT INTO ts1 (tm) VALUES (sys_guid());

4   END LOOP;

5 END;

测试的SQL语句:

1 SELECT tab2clob(CAST(COLLECT(tm) AS str2tbltype)) attributes

2   FROM ts1

3  WHERE rownum < 1000

注意:

如下的SQL语句错误:由于类型不同

1 SELECT sys_util.tab2clob(CAST(COLLECT(deptno) AS str2tbltype))

2   FROM (SELECT DISTINCT deptno FROM emp)

会抛出如下的异常信息:

因为在str2tbltype中声明的是varchar2,但是现在deptno是数字,所以数据类型会发生不一致,所以,可以使用to_char见其进行转换,来避免上述的错误:

1 SELECT sys_util.tab2clob(CAST(COLLECT(to_char(deptno)) AS str2tbltype))

2   FROM (SELECT DISTINCT deptno FROM emp)

 二:使用Oracle的SQL提供的处理XML的语句:XMLAGG()

SQL语句如下:

1 SELECT rtrim(xmlagg(xmlparse(content ename || ',' wellformed) ORDER BY ename)

2              .getclobval(),

3              ',') attributes,

4        deptno

5   FROM emp

6  GROUP BY deptno;

 

 

   或者使用如下的语句,可以实现同样的功能:

 参考网站:http://www.williamrobertson.net/documents/one-row.html

1  SELECT deptno,

2        trim(xmlagg(xmlelement(content, ename || ',' ) ORDER BY ename)

3              .extract('//text()').getclobval())

4               AS concatenated

5   FROM emp

6  GROUP BY deptno;

下面的语句,没有调用getClobVal(),聚合的结果集是字符串

1  SELECT deptno,

2        trim(xmlagg(xmlelement(content, ename || ',' ) ORDER BY ename)

3              .extract('//text()'))

4               AS concatenated

5   FROM emp

6  GROUP BY deptno;

关于Oracle中XML的知识,请参考:http://www.oratechinfo.co.uk/sqlxml.html

 

WMSYS.WM_CONCAT使用方法如下:
SELECT CUST_NO,

                       SUM(AC.MONEY) AS MONEY,

                       SUM(AC.INVOPRINT) AS INVOPRINT,

                       MIN(AC.STARTTIME) AS STARTTIME,

                       MAX(AC.ENDTIME) AS ENDTIME,

                       WMSYS.WM_CONCAT(AC.ACCOUNTNO) ACCOUNTNO

                  FROM T_ACCOUNT AC,

                       T_FEETYPE FEE,

                       --T_SUBMITDETAILTOACCOUNT S,

                       (SELECT ACCOUNTNO, ACCTYPEID

                          FROM T_ACCUSTACCBOOKDETAIL

                         GROUP BY ACCOUNTNO, ACCTYPEID) D

                 WHERE AC.FEECODE = FEE.FEECODE

                      --AND AC.ACCOUNTNO = S.ACCOUNTNO

                   AND AC.ACCOUNTNO = D.ACCOUNTNO

                   AND D.ACCTYPEID = '0001'

                   AND AC.ACCSTATUS = '4'

                   AND AC.INVOPRINT = 0

                   AND FEE.FEETYPE_TYPE = :feeType

                      --AND S.FLAG = '1'

                   AND AC.PAYDATE >= TO_DATE(:startdate, 'YYYY-MM-DD')

                   AND AC.PAYDATE < TO_DATE(:enddate, 'YYYY-MM-DD') + 1

                 GROUP BY CUST_NO

 

你可能感兴趣的:(wm_concat)