ORACLE字符串緩衝區過小解決方案

今天遇到一個字符串緩衝區過小的問題的,原由在於使用了ORACLE的聚合拼接函數WM_CONCAT,報錯信息以下: java

### Error querying database.  Cause: java.sql.SQLException: ORA-06502: PL/SQL: 數字或值錯誤 :  字符串緩衝區過小
ORA-06512: 在 "WMSYS.WM_CONCAT_IMPL", line 30


實際報錯的SQL異常複雜,現抽取出來大概是這樣子: sql

SELECT WMSYS.WM_CONCAT(DISTINCT COMPNAME) FROM 
(SELECT * FROM 
(SELECT NEWSCODE,COMPCODE FROM T_NEWS_COMPANY_BD) A
INNER JOIN TQ_COMP_INFO C
ON A.COMPCODE = C.COMPCODE) GROUP BY NEWSCODE

因爲按NEWSCODE分組後,有部分組中COMPNAME數量過多,致使拼接後大於4000個字符,而ORACLE又太笨,不會直接加省略號忽略後面的結果,而是選擇報錯. 函數

在網上也搜了一些解決方案,要麼是自定義聚合函數,要麼是用CLOB字段處理,或者再嵌套幾層過濾掉過多的記錄,感受都太過於複雜,不便迅速解決問題。思考了很久,終於想到使用PARTITION BY來解決這個問題,解決後的SQL以下: 性能

SELECT WMSYS.WM_CONCAT(DISTINCT CASE WHEN RANK < 100 THEN COMPNAME END) FROM 
(SELECT * FROM 
(SELECT NEWSCODE,COMPCODE,RANK() OVER(PARTITION BY NEWSCODE ORDER BY COMPCODE) RANK FROM T_NEWS_COMPANY_BD) A
INNER JOIN TQ_COMP_INFO C
ON A.COMPCODE = C.COMPCODE) GROUP BY NEWSCODE

這種方法須要修改的SQL代碼量極少,若是不在意後面省略掉的字段與PARTITION BY所形成的略微的性能損失的話,我的以爲是最佳解決方案。 spa

若是有朋友有更好的解決方案,麻煩告訴我。 code

相關文章
相關標籤/搜索