今天我在将我们的连接的MySQL的项目改成连接Oracle项目的时候,也是正在更改SQL的时候,发现了一个问题,就是将MySQL中的group_concat()更改为wm_concat()的时候,发现wm_concat()已经不起作用了
而已这个问题浪费了我很多时间,所以今天写了这个博客,希望能早日解决其他更多朋友的问题
在此我要声明,WMSYS_CONCAT()只适用于oracle10.0及之前的版本,且该oracle函数并不是官方规定的函数,Oracle官方的态度是其从来没有将该函数列入任何官方文档中,这个函数仅仅是让Oracle Dev研发在针对内部对象例如SYS的存储过程、字典表等使用的,并没有鼓励普通的应用开发者去使用该WMSYS.WM_CONCAT函数,但是由于部分应用开发者发现了这个函数,而且觉得较为好用,所以在应用程序编写过程中大量使用该函数,其结果是由于Oracle对该函数在后续版本中的修改(包括fix、增强)乃至于完全去掉这个函数都是有可能的。
在新的11.2中没有找到该WMSYS.WM_CONCAT函数,也就意味着其应用程序无法在11.2上正常运行。导致现在在使用的过程中会发生因为oracle数据库版本升级后,该函数失效,从而使得sql语句报错,如下:
[Err] ORA-00904: "WM_CONCAT": invalid identifier
如blog:http://www.askmaclean.com/archives/wmsys-wm_concat.html所述
我们可以替换为listagg,因为Oracle官方的态度是在11.2中应当使用 listagg函数而非WMSYS.WM_CONCAT。
关于LISTAGG:
Oracle® Database SQL Language Reference 11g Release 2 (11.2)
Oracle® Database SQL Language Reference 12c Release 1 (12.1)
这里我就只提供listagg的用法,如下:
listagg(字段名,',') within GROUP(ORDER BY 字段名) 字段名
即可!!!
当然,你也可以order by null,也是可以哒,别忘了。
列如MySQL中:
GROUP_CONCAT( t3.factor ) factor,
那么我会改成
listagg(t3.factor,',') WITHIN GROUP (ORDER BY t3.factor) AS factor,
那还有一种,有去重的,咋办~如下:
GROUP_CONCAT( DISTINCT t3.factor ) factor,
改为:
regexp_replace(listagg(t3.factor,',') WITHIN GROUP (ORDER BY t3.factor), '([^,]+)(,\1)*(,|$)', '\1\3') AS factor,
即可,
别问我是怎么改出来的,我给忘了。。。
希望能帮到各位。
在改为 listagg 后,有的时候回报错。。。
反正我是在今天遇见了,今天再接着说说这个问题。
这个错误,不要考虑,绝对是 listagg 引起的,
解决的方案无非2中(暂时发现就两种。。。)
要么你把字段类型改成 club ,要么,截取。
正常如下:
listagg(t3.factor,',') WITHIN GROUP (ORDER BY t3.factor) AS factor,
改成如下:
xmlagg(xmlparse(t3.factor||',' wellformed) order by t3.factor).getclobval()
如果你用了类似 sum 之类的函数,那你就会发现,一直报 group by 的问题,这个就是将,除了 xmlagg 和 sum 类型类似的函数以外的所有字段都给他 group by 了
好比我的:
SELECT
t3.type_code "type_code",
t3.type_name "type_name",
t3.ne_code "ne_code",
CASE t3.parent_type WHEN '1' THEN '不好用' WHEN '2' THEN '不稳定' WHEN '3' THEN '不可用' END "netState",
xmlagg(xmlparse(content t3.factor||',' wellformed) order by t3.factor).getclobval() "factor",
sum( t3.cellNum ) "cellNum"
FROM tb_lte_alarm_type t3
WHERE t3.type_code != 000 AND t3.ne_code is not null
GROUP BY t3.type_code,t3.type_name,t3.parent_type
ORDER BY t3.type_code ASC
呃,看SQL看重点,别老揪着一处看这是什么意思,做什么的。。。