1. 程式人生 > >Oracle列轉行函數版本不兼容解決方案

Oracle列轉行函數版本不兼容解決方案

版本 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列轉行函數版本不兼容解決方案