參考網址:
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)函數:
| 1234567891011 | 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 LOOP3 INSERT INTO ts1 (tm) VALUES (sys_guid());4 END LOOP;5 END;測試的SQL語句:
1 SELECT tab2clob(CAST(COLLECT(tm) AS str2tbltype)) attributes2 FROM ts13 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 deptno5 FROM emp6 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 concatenated5 FROM emp6 GROUP BY deptno;下面的語句,沒有調用getClobVal(),聚合的結果集是字符串
1 SELECT deptno,2 trim(xmlagg(xmlelement(content, ename || ',' ) ORDER BY ename)3 .extract('//text()'))4 AS concatenated5 FROM emp6 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轉自:http://www.cnblogs.com/superjt/p/4262563.html
新聞熱點
疑難解答