最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

oracle轉(zhuǎn)mysql語句轉(zhuǎn)換實(shí)例代碼

 更新時(shí)間:2023年06月07日 10:37:24   作者:supuerlovepc  
最近由于公司業(yè)務(wù)上需要,需要將原項(xiàng)目的數(shù)據(jù)庫由oracle轉(zhuǎn)換成mysql,下面這篇文章主要給大家介紹了關(guān)于oracle轉(zhuǎn)mysql語句轉(zhuǎn)換的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

場(chǎng)景:Oracle數(shù)據(jù)庫 -> TD數(shù)據(jù)庫(騰訊),而TD數(shù)據(jù)庫實(shí)質(zhì)上是對(duì)mysql數(shù)據(jù)庫的封裝拓展。因此,需要對(duì)項(xiàng)目中oracle的sql進(jìn)行適配性轉(zhuǎn)化,即在sql查詢結(jié)果不變的前提下,轉(zhuǎn)換成符合mysql語法的sql語句。

tips:其實(shí)TD數(shù)據(jù)庫8.0以上版本的語法大部分是可以完美兼容oracle語法的。但是我們的版本是5.7,因此許多函數(shù)和語法是不兼容oracle。如果你的td數(shù)據(jù)庫版本在8以上,就不用往下看了。

一、oracle函數(shù) -> mysql函數(shù)

1. decode -> case when

-- oracle: decode
select decode(1, 1, 'out1', 2, 'out2') from dual; -- out1
select decode(2, 1, 'out1', 2, 'out2') from dual; -- out2
select decode(3, 1, 'out1', 2, 'out2') from dual; -- null
--mysql: 1. case [col_name] when
select case 1 when 1 then 'out1' when 2 then 'out2' end; -- out1
select case 2 when 1 then 'out1' when 2 then 'out2' end; -- out2
select case 3 when 1 then 'out1' when 2 then 'out2' end; -- null
-- mysql: 2. case when [expr]
select case when 1 > 0  then 'out0' end; -- out0
1和2的區(qū)別在于,1中case后只能跟列,而2中case when后是可以跟表達(dá)式的,適合復(fù)雜情況

2. NVL(exp1,exp2) -> ifnull

-- oracle: nvl(param, val)
select nvl(null, 1) from dual; -- 1
select nvl('', 1) from dual;   -- 1
select nvl('0', 1) from dual;  -- 0
-- mysql: ifnull(param, val)
select ifnull(null,1);-- 1
select ifnull('',1);  -- ''
select ifnull('0',1); -- 0
nvl中null和''都輸出1,是因?yàn)閛racle中,空值''即為null
select '' from dual;  -- null
而ifnull中''輸出'',是與oracle不同的,因此在進(jìn)行函數(shù)替換的時(shí)候,要注意,
如果條件值不為''時(shí),才與nvl等價(jià)。如數(shù)字類型不會(huì)為''
如果param可能為''時(shí),需要用case when等價(jià)替換,例如:
select case param when '' then 'empty' when null then 'nul' else 'val end';

3. NVL2(exp1,exp2,exp3) -> if(expr1,expr2,expr3)

-- oracle nvl2(exp1,exp2,exp3) 
select nvl2(1, '123', 'null') from dual;  -- 123
select nvl2('', '123', 'null') from dual;  -- null
select nvl2(null, '123', 'null') from dual;  -- null
--mysql if(param,notNullVal,nullVal) 
select if(1, 123, 'null');-- 123
select if('', 123, 'null');-- null
select if(null, 123, 'null');-- null
此時(shí)看起來是等同的,那就大錯(cuò)特錯(cuò)了。
接下來看數(shù)據(jù)庫實(shí)際情況:
-- oacle: int_col_0 是int類型 值為0 
select nvl2(int_col_0, 123, null) from demo where id = '1'; -- 123
-- mysql: int_col_0 是int類型 值為0 
select if(int_col_0, 123, null) from demo where id = '1'; -- null
這時(shí)候兩個(gè)函數(shù)的結(jié)果就不一樣了。
原因如下:if(param,notNullVal,nullVal)函數(shù)中,如果param是varchar類型,當(dāng)param
值為''時(shí),會(huì)輸出后值;如果param時(shí)int類型,當(dāng)param值為0時(shí),會(huì)輸出后值;當(dāng)param是
decimal類型,當(dāng)param為0.0時(shí),會(huì)輸出后者。
得出結(jié)論:當(dāng)param的值為其數(shù)據(jù)類型的默認(rèn)值時(shí),if()函數(shù)會(huì)走后者。
因此,在param數(shù)據(jù)類型為varchar時(shí),與nvl2函數(shù)是等價(jià)的。

4. TO_NUMBER(exp) -> CAST(value AS datatype)

-- 這個(gè)沒什么講的,可以直接用,在mysql中cast函數(shù)用于將數(shù)據(jù)類型強(qiáng)轉(zhuǎn)為其它數(shù)據(jù)類型
類似于java。
select CAST('123' AS decimal(5,1) ); -- 123.0

5. to_char

a. to_char(date, dateFormatType) -> date_format(date, dateFormatType)

-- oracle: to_char(date, dateFormatType)
select to_char(sysdate, 'yyyymmdd') from dual; -- 20230222
-- mysql: date_format(date, dateFormatType)
select date_format(now(), '%Y%m%d'); -- 20230222

b. to_char(str) -> CAST(value AS char)

-- oracle to_char
select to_char(sysdate) from dual; -- [varchar2] 22-2月 -23
--mysql: cast(value AS char)
select cast(now() as char ); -- [varcahr]2023-02-22 09:10:02

6. TRUNC() -> DATE()

-- oracle trunc()
SELECT TRUNC(sysdate) from DUAL; -- [DATE]2023-02-21 00:00:00
SELECT TRUNC(to_date('20210101','yyyymmdd')) from DUAL; -- [DATE]2021-01-01 00:00:00
-- mysql date()
SELECT DATE(NOW()); -- [DATE]2023-02-21
SELECT DATE('20210201'); -- [DATE]2021-02-01

7. to_date -> str_to_date

-- oracle: to_date
select to_date('20210101', 'yyyymmdd') from dual; -- 2021-01-01 00:00:00
-- mysql : str_to_date
select str_to_date('20210101', '%Y%m%d'); -- 2021-01-01

8. 常用時(shí)間格式轉(zhuǎn)換

oracle  ->  mysql
YYYYmmdd -> %Y%m%d
YYYY-mm-dd -> %Y-%m-%d 
yyyy-mm-dd hh24:mi:ss -> %Y-%m-%d %H:%i:%s

9. 時(shí)間計(jì)算方式

a. 日期+/-1天

-- oracle 
select to_date('20210101', 'yyyymmdd') - 1 from dual; -- 2020-12-31 00:00:00
-- mysql
select str_to_date('20210101', '%Y%m%d') - 1 from dual; -- 20210100
從結(jié)果可以看出是錯(cuò)誤的,只是單純-1,并沒有校驗(yàn)時(shí)間是否正確。
-- mysql adddate(date, [num])
select adddate(str_to_date('20210101', '%Y%m%d'), -1); -- 2020-12-31
-- mysql date_sub/date_add(date, interval [num] [day/month/year...])
select date_sub(str_to_date('20210101', '%Y%m%d'), interval 1 day ); -- 2020-12-31
select date_add(str_to_date('20210101', '%Y%m%d'), interval 1 day ); -- 2021-01-02
其中interval后可跟如下時(shí)間單位:
FRAC_SECOND
SECOND
MINUTE
HOUR
DAY
WEEK
MONTH
QUARTER
YEAR

b. 日期+/-1月/年

-- oracle  add_months(date, num)
select add_months(to_date('20210101','yyyymmdd'), 1) from dual; -- 2021-02-01 00:00:00
-- mysql date_add(date,, interval [num] month)
select date_add(str_to_date('20210101', '%Y%m%d'), interval 1 month ); --2021-02-01
-- mysql 
SELECT TIMESTAMPADD(SQL_TSI_MONTH, 1, str_to_date('20210101', '%Y%m%d')); -- 2021-02-01
tips:
mybatis中使用date_add時(shí),一旦里賣弄interval關(guān)鍵字,總是會(huì)sql編譯失敗,
不知道是否和版本還是什么有關(guān)。
使用TIMESTAMPADD函數(shù)不會(huì)報(bào)錯(cuò)。
interval-type間隔類型參數(shù)如下:
SQL_TSI_FRAC_SECOND
SQL_TSI_SECOND
SQL_TSI_MINUTE
SQL_TSI_HOUR
SQL_TSI_DAY
SQL_TSI_WEEK
SQL_TSI_MONTH
SQL_TSI_QUARTER
SQL_TSI_YEAR

10. SUBSTR() -> SUBSTRING()

-- 截取字符串:
注意:
-- oracle
select SUBSTR('123456', 1, 3)、SUBSTR('123456', 0, 3) from dual; -- 輸出都是123;
-- mysql
select SUBSTRING('123456', 1, 3); -- 輸出123  
select  SUBSTRING('123456', 0, 3); --輸出空值''

11. 拼接符號(hào)|| -> concat(str, str1)

-- mysql concat(str1,str2,...)
select concat('1','2','3','4','A'); -- 1234A

12. length() -> char_length()

-- oracle length()
select char_length(''); -- null
select LENGTH('123'), '123' from dual; -- 3
select LENGTH(0.00), 0.00 from dual; -- 1
select LENGTH(0), 0 from dual; -- 1
select LENGTH(0.000001), 123456 from dual; -- 7
select LENGTH(sysdate), sysdate from dual; -- 9 2023-02-22 01:23:39
-- mysql char_length
select char_length(''); -- 0
select char_length(123); -- 3
select char_length(0); -- 1
select char_length(0.0); -- 3
select char_length(0.000001); -- 8
select char_length(now()), now(); -- 19  2023-02-22 09:18:34
tips:
可以看出,oracle的length()對(duì)于字符串的長(zhǎng)度計(jì)算結(jié)果是符合我們預(yù)期的,但是數(shù)字類型和并不會(huì)把
小數(shù)點(diǎn)的長(zhǎng)度加上。且當(dāng)為0.0000時(shí),會(huì)自動(dòng)轉(zhuǎn)會(huì)為0再做長(zhǎng)度計(jì)算,得出結(jié)果為1.時(shí)間格式
時(shí)摻長(zhǎng)度我也不確定是怎么得出的。
mysql的char_length()結(jié)果就比較符合我們的期望。會(huì)把所有參數(shù)都轉(zhuǎn)化為char類型后,再進(jìn)行
長(zhǎng)度計(jì)算。
注意:當(dāng)字符串計(jì)算長(zhǎng)度時(shí),如果字符串為空'',oracle-length()的結(jié)果為null,mysql-
char_length的結(jié)果為0。

二、oracle語法 -> mysql語法

有些語法也不是通用的,下面是經(jīng)常見到的幾種。

1. 臨時(shí)表with as

解決方案1:換成子查詢放到表調(diào)用處

解決方案2:在java中拆分,減少sql復(fù)雜度。

2. 左右連接(+)寫法

解決方案:根據(jù)原sql where后的表連接條件,有(+)的換成left join,沒有的換成inner join

3. 遞歸 connect by prior

解決方案:這塊內(nèi)容比較多,另開了一篇:[‘@實(shí)現(xiàn)mysql遞歸查詢’]

4. merge語法

解決方案:sql拆成查詢、更新、插入三個(gè)語句。在java中組合調(diào)用

總結(jié)

到此這篇關(guān)于oracle轉(zhuǎn)mysql語句轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)oracle轉(zhuǎn)mysql語句內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 修改Mysql root密碼的方法

    修改Mysql root密碼的方法

    這篇文章主要介紹了修改Mysql root密碼的方法的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-11-11
  • MySQL中使用PROFILING來查看SQL執(zhí)行流程的實(shí)現(xiàn)步驟

    MySQL中使用PROFILING來查看SQL執(zhí)行流程的實(shí)現(xiàn)步驟

    在MySQL中,PROFILING功能提供了一種方式來分析SQL語句的執(zhí)行時(shí)間,包括查詢執(zhí)行的各個(gè)階段,如發(fā)送、解析、優(yōu)化、執(zhí)行等,這對(duì)于診斷性能問題非常有用,本文給大家介紹了MySQL中使用PROFILING來查看SQL執(zhí)行流程的實(shí)現(xiàn)步驟,需要的朋友可以參考下
    2024-07-07
  • 最新評(píng)論

    红安县| 济阳县| 五台县| 兰西县| 安义县| 保靖县| 临沭县| 新泰市| 天台县| 金川县| 贡嘎县| 湾仔区| 珲春市| 井冈山市| 枝江市| 峨眉山市| 清水河县| 兖州市| 嵩明县| 大足县| 滕州市| 两当县| 延长县| 清新县| 呼和浩特市| 长阳| 青铜峡市| 安塞县| 大港区| 西充县| 长乐市| 商都县| 当阳市| 黄梅县| 宁远县| 扎鲁特旗| 铜山县| 吉隆县| 盖州市| 蒙山县| 罗城|