@
最近在做項目遷移,Oracle版本的遷到Mysql版本,遇到有些oracle的函數,mysql並沒有,所以就只好想自定義函數或者找到替換函數的方法進行改造。
所以本博客主要介紹Oracle兼容mysql改造方式以及注意事項,也就是介紹原本Oracle一些函數在Mysql的替換方法等等,適合給原本是Oracle版本的項目,想兼容Mysql版本。
(1) 模糊匹配
Oracle的模糊匹配和mysql是不同的,在mybatis項目里,用Oracle,我們可能會這樣寫:where a like '%'|| #{參數} ||'%'
,不過放在mysql就不兼容了,mysql的做法是這樣的where a like concat('%', #{參數} ,'%')
(2) 刪除數據
一個小細節,在Oracle里刪除數據,delete 表格 t where t.id = '?'
或者 delete from 表格 t where t.id = '?'
不加關鍵字from或者用和不用別名t都是可以的,不過放在mysql5.X就不可以了,其它Mysql版本沒驗證過,Mysql版本要求必須加關鍵字from同時不能加別名 delete from 表格 where id = '?'
(3) 時間函數
Oracle的時間函數和Mysql的時間函數是不同的,Oracle的格式是to_date('2019-02-12 14:20:22', 'yyyy-mm-dd hh24:mi:ss'),Mysql的格式是str_to_date('2019-02-12 11:34:32', '%Y-%m-%d %H:%i:%s')
(4) 關鍵字問題
在Oracle還是mysql建表的時候,一般都不要用數據庫關鍵字做表的字段,比如Order,CONDITION等等,特別是mysql就直接報錯。假如用CONDITION做表字段,在寫入數據的時候就要用CONDITION
,加“`”符號,例子
insert into table (UUID, `CONDITION`, FLAG,CREATE_TIME)
values ('EAF472C6332241FBBBB22A37336BBD65', '', '${voteLZ_Boolean}', 'control/doApprFlowNew', str_to_date('13-06-2018 17:38:33', '%d-%m-%Y %H:%i:%s'));
(5) 遞歸查詢
oracle實現遞歸查詢的話,就可以使用start with … connect by,mysql並沒有通過類似函數,解決方法是通過自定義函數的方法,具體可以參考我這篇博客
https://blog.csdn.net/u014427391/article/details/87297884
(6) 排序問題
oracle做數據排序的時候,有時候可以用nulls first或者nulls last將null值排在最前或者最后。
不過遷到Mysql的話,mysql並沒有提供類似函數,所以要怎么實現?下面給出解決方法:
null值排在最后,用Mysql的IF和ISNULL函數。如果為空返回1,否返回0
select * from A order by IF(ISNULL(a),1,0),a desc
null值排在最前,用Mysql的IF和ISNULL函數。如果為空返回0,否返回1
select * from A order by IF(ISNULL(a),0,1),a desc
具體可以參考我寫的這篇博客:https://blog.csdn.net/u014427391/article/details/87297068
(7) 空值返回0
業務是這樣的,加入查詢到一個參數為null的話,就返回0,在Oracle里,可以用nvl函數nvl(參數,0),意思是參數為null,就返回0,避免空指針報錯
介紹一下oracle的nvl函數和nvl2函數。
nvl函數
nvl函數基本語法為nvl(E1,E2),意思是E1為null就返回E2,不為null就返回E1。
nvl2函數
nvl2函數的是nvl函數的拓展,基本語法為nvl2(E1,E2,E3),意思是E1為null,就返回E3,不為null就返回E2。
nvl函數具體可以參考我這篇博客:https://blog.csdn.net/u014427391/article/details/84996009
上面是Oracle的做法,mysql的做法可以用IFNULL(參數,0)
函數
(8) 取最大值
Oracle和Mysql取最大值都可以用max函數,不過Oracle有提供partition by和開窗函數的方法實現去最大值,開窗函數具體可以參考我以前的博客:https://blog.csdn.net/u014427391/article/details/85412064
Oracle例子
<select id="getMaxVaue" parameterType="java.lang.String" resultType="java.lang.Integer" databaseId="oracle" >
select nvl(參數,0)
from (select 參數,
row_number() over(partition by id order by 參數 desc) rn
from 表格
) t
where t.rn = 1
</select>
Mysql例子
<select id="getMaxValue" parameterType="java.lang.String" resultType="java.lang.Integer" databaseId="mysql" >
select IFNULL(MAX(參數),0) from 表格
</select>
(9) 列轉換函數
Oracle列轉行函數可以用vm_comcat函數,mysql的用concat_ws函數,語法類似
Oracle列轉行函數的可以參考我以前博客:https://blog.csdn.net/u014427391/article/details/84981114
列轉行函數不兼容問題:https://blog.csdn.net/u014427391/article/details/84867390
(10) 類型轉行函數
Oracle類型轉換函數cast語法是類似的,不過Oracle是沒有int類型,只有number類型,所以就略有不同了