Oracle列轉行函式版本不相容解決方案
業務場景
本部落格記錄一下Oracle列轉行函式在Oracle11的一些不相容問題,vm_concat在一些業務場景是必須的。不過這個函式使用要謹慎,底層實現應該也是group by等等實現的,效能並不是特別好。這個函式在Oracle12是沒有的,在Oracle11是不太相容的,Oracle10可以正常使用。最近遇到這個問題,網上部落格很多都寫到了自定義列轉行函式的辦法去解決。但是這種辦法並不一定適用所有的業務場景。我並沒有採用。不過有些場景還是可以使用的。
網上優秀例子
下面是網路記錄比較詳細的例子
ofollow,noindex">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