日期:2014-05-17  浏览次数:23896 次

listagg 字符串连接的结果过长
若表client_group
oid facility_oid client_group_desc
1 2 A
2 2 B
3 2 C

select cg.facility_oid,listagg(cg.client_group_desc,',') within group (
  ORDER BY cg.client_group_desc) AS client_group_desc_list from client_group cg group by cg.facility_oid;

输出结果为
facility_oid client_group_desc_list
2 A,B,C

若这里的client_group_desc非常长,比如把A 换成2000个A,B换成2000B
则client_group_desc_list的长度大于4000,就会报 字符串连接的结果过长 的错误

请问有没有简单点的办法来解决这个问题呢?

比如能否对listagg的返回值进行修改,让它自动截掉4000后的字符,或者修改listagg的返回值类型,将varchar2换成clob?

------解决方案--------------------
没有办法,这个函数的返回值是varchar2类型,你改不了。除非写存储过程,在pl/sql中,字符串长度可以达到32768,然后用一个clob来存
超出的部分不截除掉倒是个办法,不过语句会复杂得多,性能也会下降
------解决方案--------------------
关于截掉多余的字符,有两种办法
第一种是按照你的估计,每个client_group_desc大概含多少字节,比如是200字节,那么先用row_number()对每个分组进行排序,每组留下最多20条记录,然后再聚合
第二种,分析函数sum(lengthb(client_group_desc))over(partition by facility_oid order by ...) 大于4000的部分截掉,然后聚合

由于手里没有11g r2的环境,只能提供个思路