数据库—-如何将oracle语句转换成mysql语句

数据库—-如何将oracle语句转换成mysql语句前言 最近由于公司业务上需要 需要将原项目的数据库由 oracle 转换成 mysql 转换的时候我们通常需要先将数据库转成 mysql 然后再去为项目添加 mysql 语句 至于如何将 oracle 数据库转换成 mysql 数据库且保证数据库数据的正确性 可以参考我的上一篇文章 这篇文章的主要作用就是来讲一下 oracle 语句中用到的那些函数 在 mysql 中应该怎么使用

前言

  最近由于公司业务上需要,需要将原项目的数据库由oracle转换成mysql,转换的时候我们通常需要先将数据库转成mysql,然后再去为项目添加mysql语句,至于如何将oracle数据库转换成mysql数据库且保证数据库数据的正确性,可以参考我的上一篇文章,这篇文章的主要作用就是来讲一下oracle语句中用到的那些函数,在mysql中应该怎么使用。


文章地址:

  将Oracle数据库转换成mysql数据库


正文

简单函数之间的转换

函数作用 oracle mysql
日期转字符串 to_char date_format
字符串转日期 to_date str_to_date
判断空值 nvl IFNULL
转换数字 to_number cast
条件判断 decode case then或if else
时间串拼接 numtodsinterval contact
decimal的转换 to_char cast(column as char)
当前时间 sysdate now() sysdate()
substring区别 开始位置可以为0 开始位置不能为0
时间的计算 可以直接相减(默认单位:天) 使用 TIMESTAMPDIFF(需指定默认单位)
分组排序 row number over 使用变量来实现

具体实例:

一、当前时间–(sysdate)

  oracle语句:

 select sysdate from dual 

  mysql语句:

 select now() select sysdate() 
二、日期转字符串–(to_char)

  oracle语句:

 select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual 

  mysql语句:

 select DATE_FORMAT(NOW(),'%Y-%m-%d %H:%i:%s') 
三、字符串转日期–(to_date)

  oracle语句:

 select to_date('2019-01-01 08:00:00', 'yyyy-mm-dd hh24:mi:ss') from dual 

  mysql语句:

 select STR_TO_DATE('2019-01-01 08:00:00',"%Y-%m-%d %H:%i:%s") 
四、判断空值–(nvl)

  oracle语句:

 NVL(a,b) 

  mysql语句:

 IFNULL(a,b) 
五、转换数字–(to_number)

  oracle语句:

 to_number(column) 

  mysql语句:

 转换成整形: cast(column as unsigned int) 转换成浮点型: cast(column as decimal(10,2)) 
六、条件判断–(decode)

  oracle语句:

 select decode(mod(quantity,7),0,'A',1,'B','C') as qtype from biz_order 

  mysql语句:

 使用case whenSelect case mod(quantity,7) when 0 then 'A' when 1 then 'B' else 'C' end as qtype from biz_order 使用if else: 不推荐使用if-else,因为我写不出来,建议使用case when,咳咳咳咳咳-----, 
七、时间串拼接–(numtodsinterval)

  oracle语句:

 select a.*, case when length(ltrim(substr(numtodsinterval(ceil(a.reportperiod), 'second'),2,15),'0')) = 6 then '0天' || substr(numtodsinterval(ceil(a.reportperiod), 'second'),12,8) when a.reportperiod is null then '' else ltrim(substr(numtodsinterval(ceil(a.reportperiod), 'second'),2,9),'0') || '天' || substr(numtodsinterval(ceil(a.reportperiod), 'second'),12,8) end as ReportWaitTime from biz_dev_fault_repair_result a 

  mysql语句:

 SELECT a.*, CONCAT( FLOOR( a.reportperiod / 86400 ), '天', LPAD( FLOOR( a.reportperiod % 86400 / 3600 ), 2, 0 ), ':', LPAD( FLOOR( a.reportperiod % 86400 % 3600 / 60 ), 2, 0 ), ':', LPAD( CEIL( a.reportperiod % 86400 % 3600 % 60 ), 2, 0 ) ) AS ReportWaitTime FROM biz_dev_fault_repair_result a 
八、decimal的转换

  oracle语句:

 select to_char(quantity) from biz_order 

  mysql语句:

 需要注意的是,在mysql中转换时不能使用as varchar//SELECT cast(quantity as VARCHAR) from biz_order ----这是错误的语法 SELECT cast(quantity as CHAR) from biz_order ----这是正确的语法 
九、substring的区别

  oracle语句:

 select substr('',0,2) from dual //返回结果12 

  mysql语句:

 select substr('',1,2) //返回结果12,即相同返回结果 
十、时间的计算

  oracle语句:

 select maintaintime,createtime,maintaintime-createtime t from biz_order //返回结果以天为单位 

  mysql语句:

 select maintaintime,createtime,TIMESTAMPDIFF(second,maintaintime,createtime) t from biz_order //返回结果以秒为单位,直接相减默认结果说实话我没看懂是以什么为单位,它是每分钟为100,秒数作为十分位和百分位,逢60就加100 

  返回结果以秒为单位,直接相减默认结果说实话我没看懂是以什么为单位,它是每分钟为100,秒数作为十分位和百分位,逢60就加100

十一、分组排序–(row_number() over)

  oracle语句:

 SELECT a.*, ROW_NUMBER() OVER(partition by a.orderchildId order by a.CheckEndTime desc) as rum_num FROM biz_qa_check_first a 

  mysql语句:

 select @rownum:=@rownum+1 rownum,a.*, if(@orderchildId=a.orderchildId,@rank:=@rank+1,@rank:=1) as rum_num, @orderchildId:=a.orderchildId from(SELECT * from biz_qa_check_first order by orderchildId,CheckEndTimedesc)a, (select @rownum:=0,@orderchildId:=null,@rank:=0)b 

补充知识说明:


  1.在mysql中如何获取当前周

  oracle语句:

 select to_char(sysdate,'iw') from dual 
 SELECT DATE_FORMAT(now(),'%u') //大写U与小写u不一样 
 %M 月名字(January……December) %W 星期名字(Sunday……Saturday) %D 有英语前缀的月份的日期(1st, 2nd, 3rd, 等等。) %Y 年, 数字, 4 位 www.2cto.com %y 年, 数字, 2 位 %a 缩写的星期名字(Sun……Sat) %d 月份中的天数, 数字(00……31) %e 月份中的天数, 数字(0……31) %m 月, 数字(01……12) %c 月, 数字(1……12) %b 缩写的月份名字(Jan……Dec) %j 一年中的天数(001……366) %H 小时(00……23) %k 小时(0……23) %h 小时(01……12) %I 小时(01……12) %l 小时(1……12) %i 分钟, 数字(00……59) %r 时间,12 小时(hh:mm:ss [AP]M) %T 时间,24 小时(hh:mm:ss) %S 秒(00……59) %s 秒(00……59) %p AM或PM %w 一个星期中的天数(0=Sunday ……6=Saturday ) %U 星期(0……52), 这里星期天是星期的第一天 %u 星期(0……52), 这里星期一是星期的第一天 %% 一个文字“%”。 

  2.mysql实现row number over的原理
 SELECT a.*, ROW_NUMBER() OVER(partition by a.orderchildId order by a.CheckEndTime desc) as rum_num FROM biz_qa_check_first a 

  mysql语句:

 select @rownum:=@rownum+1 rownum,a.*, if(@orderchildId=a.orderchildId,@rank:=@rank+1,@rank:=1) as rum_num, @orderchildId:=a.orderchildId from(SELECT * from biz_qa_check_first order by orderchildId,CheckEndTimedesc)a, (select @rownum:=0,@orderchildId:=null,@rank:=0)b 

假如我们的数据库对应的数据是下表

orderchildid
10
10
10
11
12

  mysqlsql运行步骤:
    查询第一行,此时的变量值

@rownum @orderchildId @rank
0 null 0
@rownum @orderchildId @rank
1 10 1
@rownum @orderchildId @rank
2 10 2
@rownum @orderchildId @rank
3 10 3
@rownum @orderchildId @rank
4 11 1
orderchildid @rank
10 1
10 2
10 3
11 1
12 1

  那么在我们做完查询之后,只需要指定查询出@rank=1的就是实现了以orderchildid分组,由于我们设置了别名,所以我们的筛选条件可以写为 where rum_num=1,这样我们就实现了分组,而在分组之前,我们的嵌套查询已经实现了排序功能。


  3.说一下mysql中表的别名问题

  比如说这条sql吧

 select *from ( select distinct a.*,e.name workshopname,f.name rolename,h.name shiftname, m.row_num from biz_base_person_group a left join biz_base_person_group_asso b on a.id=b.GroupId left join biz_base_person_group_dev d on a.id = d.groupid left join biz_base_workshop e on a.workshopid = e.id left join sys_role f on a.roleid = f.id left join biz_base_shift g on a.classcode = g.code left join v_sys_dict h on g.code = h.code and h.pCode = 'ShiftType' and h.type = 'zh_CN' left join (select a.id ,if(@id=a.id,@rank:=@rank+1,@rank:=1) as row_num, @id:=a.id from (SELECT *from biz_base_person_group order by id) a) m on a.id = m.id ) a where a.row_num = 1 order by maintaintime desc 

  4.使用mysql实现rownum

   首先看一下oracle的语句:

 select rownum rn ,a.* from ( select a.*,b.name typename,c.value from sys_res_i18n a left join sys_dict b on a.type = b.code and b.pcode = 'I18nType' left join sys_res_i18n_type c on a.id = c.pid and c.type = 'zh_CN' order by a.id desc ) a 
 select @rownum:=@rownum+1 rn,a.* from ( select a.*,b.name typename,c.value from sys_res_i18n a left join sys_dict b on a.type = b.code and b.pcode = 'I18nType' left join sys_res_i18n_type c on a.id = c.pid and c.type = 'zh_CN' order by a.id desc ) a, (SELECT @rownum:=0) b 
 select cast(@rownum:=@rownum+1 as char) rn,a.* from ( select a.*,b.name typename,c.value from sys_res_i18n a left join sys_dict b on a.type = b.code and b.pcode = 'I18nType' left join sys_res_i18n_type c on a.id = c.pid and c.type = 'zh_CN' order by a.id desc ) a, (SELECT @rownum:=0) b 

  补充: 并不是所有的rownum都需要这么来实现,假如前台不需要rownum的值,你可以看一下具体的业务,很可能他的sql只是想取出第一条数据,在mysql中你可以直接使用limit关键字就能拿到数据。


  5.使用mysql执行语句块

  在Oracle中执行语句块应该以下面的形式:

 begin insert into sys_sequence(ObjectName, Id, CreateTime) select '${tableobjname}', 1, sysdate from dual where not exists ( select 1 from sys_sequence where ObjectName = '${tableobjname}') ; update sys_sequence set id = (select nvl(max(id), 1) from ${tableobjname}) where ObjectName = '${tableobjname}'; end; 

在mysql中执行语句块,不需要添加begin和end

 insert into sys_sequence(ObjectName, Id, CreateTime) select '${tableobjname}', 1, sysdate from dual where not exists ( select 1 from sys_sequence where ObjectName = '${tableobjname}') ; update sys_sequence set id = (select nvl(max(id), 1) from ${tableobjname}) where ObjectName = '${tableobjname}'; 

  6.自增ID
 select seq_id.nextval from dual 

MySQL:更改表中需要自增的列,如id,更改语句如下:

 alter table biz_order modify id int auto_increment primary key 

  在mysql中执行插入时,就不用列出id。

  7.使用mysql实现merge into

oracle语句:

 merge into biz_url_request_para a using (select #{clientid} as clientid, #{url} as url, #{para} as para from dual) b on (a.clientid = b.clientid and a.url = b.url and a.clientid = #{clientid})  when matched then update set a.para = b.para, timestamp = to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') when not matched then insert values(#{clientid}, #{url}, #{para}, to_char(sysdate,'yyyy-mm-dd hh24:mi:ss')) 

mysql

 insert into biz_url_request_para ( clientid, url, para, timestamp ) values ( #{clientid}, #{url}, #{para}, date_format(now(),'%Y-%m-%d %H:%i:%s') ) on duplicate key update para = values(para), timestamp = values(timestamp) 
  8.mysql实现connect by

  首先,关于connect by这个用法我也不是很清楚,具体的大家可以参考这篇文章,但是我这里举的例子,因为功能业务的需求,不是像下面文章一样的例子。在mysql中,这里这处业务的实现通过substring_index函数来实现,同样也有一篇推荐文章。下面我会解释我所要讲的内容。



SELECT a.id,SUBSTRING_INDEX(SUBSTRING_INDEX(a.exceptiontype,',',b.Id+1),',',-1) as name from biz_mold_maintain_result a left join v_biz_seq_id b on b.Id < (LENGTH(a.exceptiontype)-LENGTH(REPLACE(a.exceptiontype,',',''))+1) where a.id=1 
  9.mysql实现sum over(partition by column)

还是先拿出oracle语句以及查询结果:

 select distinct a.scrapreason, sum(a.scrapcount) over(partition by a.itemid) as scrapcount, sum(a.scrapcount) over(partition by a.factoryid) as count from da_qa_scrap_daily a left join biz_base_workshop b on a.workshop = b.code and a.factoryid = b.factoryid where 1=1 and a.checktype = 'QaCheckFirst' 
 select distinct a.*,b.count count from ( select a.*,b.name workshopname,b.id workshopid ,sum(a.scrapcount) itemscrapcount from da_qa_scrap_daily a left join biz_base_workshop b on a.workshop = b.code and a.factoryid = b.factoryid where 1=1 and a.checktype = 'qacheckfirst' group by a.itemid ) a left join ( select a.*,sum(a.scrapcount) count from da_qa_scrap_daily a left join biz_base_workshop b on a.workshop = b.code and a.factoryid = b.factoryid where 1=1 and a.checktype = 'qacheckfirst' group by a.factoryid ) b on a.factoryid=b.factoryid 

  如果你有更好的实现方法,欢迎在下面评论留言或者私信我。


  由于写的都是在转换过程中遇到的一些函数问题,所以整理了一下,当然也有未解决的问题,比如oracle中的connect by函数的实现,我在网上看的教程就是通过自己创建存储过程来实现同样的效果,这个就涉及到我的知识盲区了,如果我弄懂了之后会在这里补充.

总结

  在这里和大家说一下转换之中的感想吧,其实在转换的时候我们大可不必担心,只要自己慢慢来,先明白原先sql的作用的,包括从哪张表的查询,查询了什么字段。在你转换的过程中,一步步的分解,先解决嵌套查询中的转换工作,在看外部查询有没有需要转换的内容,大部分的函数mysql和oracle中还是相同的,比如一些聚合函数的使用,这都不需要你更改。转换时要细致。

  如果文章哪里有写的不对的地方,欢迎指出!!!


  咸鱼IT技术交流群:,在这里有一群和你一样有爱、有追求、会生活的朋友! 大家在一起互相支持,共同陪伴,让自己每天都活在丰盛和喜乐中!同时还有庞大的小伙伴团体,在你遇到困扰时给予你及时的帮助,让你从自己的坑洞中快速爬出来,元气满满地重新投入到生活中!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/213877.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午5:27
下一篇 2026年3月18日 下午5:27


相关推荐

  • 【8】Ubuntu18.04 卸载Pycharm2020.2

    【8】Ubuntu18.04 卸载Pycharm2020.2在尝试用激活工具来激活成功教程 pycharm2020 2 版本的时候突然 pycharm 无法打开 就尝试卸载重装 根据网伤提供的方法 最终只有下面这个方法对我有用 附上链接 感谢博主 撒花 https blog csdn net chengyq116 article details utm medium distribute pc aggpage search result none task blog 2allfirst rank v2 rank v25 4 noneca

    2026年3月19日
    3
  • prepareStatement与Statement的区别

    prepareStatement与Statement的区别prepareStatement与Statement的区别1.区别:stmt=conn.CreateStatement();resultSetrs=stmt.executeQuery(sql);上面是statement的用法============================下面是PrepareStatement的用法ptmt=conn.Prepa

    2022年5月29日
    49
  • 什么是SSH 以及常见的ssh 功能

    什么是SSH 以及常见的ssh 功能什么是SSH?简单说,SSH是一种网络协议,用于计算机之间的加密登录。如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机,我们就可以认为,这种登录是安全的,即使被中途截获,密码也不会泄露。最早的时候,互联网通信都是明文通信,一旦被截获,内容就暴露无疑。1995年,芬兰学者TatuYlonen设计了SSH协议,将登录信息全部加密,成为互联网安全的一个基本解决方案,迅速在全世界获得推广,目…

    2022年7月13日
    15
  • 亲测无限坐席在线客服系统源码,基于ThinkPHP的一款在线客服系统源码

    亲测无限坐席在线客服系统源码,基于ThinkPHP的一款在线客服系统源码源码简介东西没问题,和别人换的本来说是多语言带机器人翻译之类的,给了个这。。。直接一键安装的,启动两个端口就行了,安装倒是简单编号:ym270品牌:无语言:PHP大小:34.5MB类型:在线客服系统支持:pc+wap亲测无限坐席在线客服系统源码,基于ThinkPHP的一款在线客服系统源码,直接一键安装的,启动两个端口就行了。安装教程:PHP5.6+MySQL5.5+设置网站运行目录为public,配置伪静态规则为thinkphp访问/install.php安装即可亲测无限坐席

    2022年7月19日
    19
  • java eventbus 原理_EventBus原理

    java eventbus 原理_EventBus原理EventBus 实现了观察者模式 使用方法非常简单 可参考 有用的 Guava 二 这篇文章主要讲解 EventBus 的实现原理 一言以蔽之 EventBus 内部有一个 map 当 register 时往 map 中增加一个元素 key 为事件的类型 value 为观察者 post 时根据事件类型找到观察者之后 对其反射调用 下面我们从 register 方法开始 publicvoidre Object

    2026年3月19日
    2
  • windowsform和wpf(winform和wpf我选哪个)

    WPF开发于WinForm之后,从技术发展的角度,WPF比WinForm先进是不容置疑的。我觉得WPF相比于WinForm有下面的一些较好的特性:解决WindowHandle问题在WindowsGDI或WinForm开发中复杂的GUI应用程序,会使用的大量的控件,如Grid等。而每个控件或Gridcell都是一个小窗口,会使用一个Windowhandle,尽管控件厂商提供了很多优化…

    2022年4月12日
    40

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号