Oracle列轉行函數版本不兼容解決方案
阿新 • • 發佈:2018-12-07
版本 where () 版本不兼容 wm_concat http class 就是 href
業務場景
本博客記錄一下Oracle列轉行函數在Oracle11的一些不兼容問題,vm_concat在一些業務場景是必須的。不過這個函數使用要謹慎,底層實現應該也是group by等等實現的,性能並不是特別好。這個函數在Oracle12是沒有的,在Oracle11是不太兼容的,Oracle10可以正常使用。最近遇到這個問題,網上博客很多都寫到了自定義列轉行函數的辦法去解決。但是這種辦法並不一定適用所有的業務場景。我並沒有采用。不過有些場景還是可以使用的。
網上優秀例子
下面是網絡記錄比較詳細的例子
https://www.cnblogs.com/hanzongze/p/oracle-wm_concat.html
解決方案
通過自定義函數解決也是可以的,不過我並不是這樣做的。
下面介紹一下我的解決方法。首先分析一下,Oracle11不兼容vm_concat列轉行函數,並不代表其它函數不兼容,或許可以找到其它代替的,通過找資料,發現了Oracle11提供的另外一個函數:listagg()函數
語法:listagg(參數,‘分隔符‘) within group(order by 參數id)
列子:to_char(listagg(ur.user_role,‘,‘ ) within GROUP (order by (ur.user_role))) userrole,
原來SQL:
select u.user_sex, u.full_name, u.user_code, to_char(wm_concat(ur.user_role)) userrole, to_char(wm_concat(r.role_name)) rolename, to_char(r.role_type) roletype, u.status from t_user u left outer join t_user_role ur on ur.user_code = u.user_code left outer join t_role r on r.user_role = ur.user_role
首先通過SQL獲取一下oracle版本號
<!-- 獲取oracle版本信息 -->
<select id="getOracleVersion" resultType="string">
SELECT * FROM v$version WHERE banner LIKE ‘Oracle%‘
</select>
下面代碼僅供參考,就是獲取oracle版本號,然後傳到mybatis的xml文件
String oracleVersion = approveConfigDao.getOracleVersion(); //eg:Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production String[] bannerArr = oracleVersion.split(" "); oracleVersion = bannerArr[2]; LOG.info("oracle版本:"+oracleVersion); map.put("oracleVersion", oracleVersion);
orm框架是用mybatis的,所以sql稍微改一下,oracle10調vm_concat,oralce11的調listagg函數
select u.user_sex,
u.full_name,
u.user_code,
<choose>
<when test="oracleVersion==‘11g‘ or oracleVersion==‘12g‘">
to_char(listagg(ur.user_role,‘,‘ ) within GROUP (order by (ur.user_role))) userrole,
to_char(listagg(r.role_name,‘,‘ ) within GROUP (order by (r.role_name))) rolename,
</when>
<otherwise>
to_char(wm_concat(ur.user_role)) userrole ,
to_char(wm_concat(r.role_name)) rolename ,
</otherwise>
</choose>
to_char(r.role_type) roletype,
u.status
from t_user u
left outer join t_user_role ur
on ur.user_code = u.user_code
left outer join t_role r
on r.user_role = ur.user_role
Oracle列轉行函數版本不兼容解決方案