Oracle数据库移植到MySQL实战

项目做好了,更高的要求被提出来,比如,要多数据库支持,怎么办?移植!有没有人做过这事,我好参考一下?哦,这有一个…
  关键词:Oracle MySQL 移植
  一、前言
  公司原来的项目是基于Oracle数据库的,Oracle功能强大,但是部署和管理较复杂,更重要的是,购买Oracle的费用不是每个客户都愿意承担的。因此,迫切需要把公司项目所用数据库移植到一个简单好用的数据库上。当然,如您所料,我们选择了广受欢迎的MySQL。
  作为一个开源数据库,MySQL用无数案例证明了她的可用性,因此让我们把重点放在如何将Oracle移植到MySQL上。已经有很多的文章和专题介绍了Oracle移植到MySQL的方法和步骤,也有相当多的工具可以辅助这种移植过程。但是,由于数据库实现的差异,完美的移植工具是不存在的,移植过程中不断碰到的问题证明了这一点,特别是您使用了Oracle的一些高级特性时。
  从Oracle移植到MySQL主要有六个方面的内容需要移植,一是表Table,包括表结构和数据,二是触发器Trigger,三是存储过程Procedure,函数function和包Package,四是任务Job,五是用户等其他方面的移植,六是具体应用程序通过SQL语句访问时的细节差异克服。
  笔者用来移植测试的数据库是:Oracle 9i ,MySQL 6.0,Windows 2000环境。
  二、表的移植
  这个部分的移植是最容易用工具实现的部分,因为很多MySQL的图形管理工具都自带这样的移植工具,比如SQLYog,MySQL Administrator等。但是,这些工具的移植能力各有不同,对字段类型转换﹑字符集等问题都有自己的处理方式,使用时请注意。
  笔者使用“SQLYog Migration Toolkit”工具按提示步骤移植后,表的主要结构和数据将成功移植,主要包括表的字段类型(经过映射转换,比如number会转换为double,date转换为timestamp等,请小心处理日期字段的默认值等),表的主键,表的索引(Oracle的位图索引会被转成BTree索引,另外表和字段的注释会丢失)等信息。需要特别注意的是,Oracle的自增字段的处理。
  大家知道,Oracle通常使用序列sequence配合触发器实现自增字段,但是MySQL和SQL Server等一样,不提供序列,而直接提供字段自增属性。所以,请把Oracle里面的自增字段实现直接改为MySQL的字段属性,而且,这个字段必须是主键(key)并且不能有默认值。
  还有一个问题,如果您的应用要直接使用Oracle的某个序列,那么您只能在MySQL里面模拟实现一个,具体方法就是利用MySQL的自增字段实现的。
  三、触发器的移植
  首先,MySQL在6.0以后才支持触发器!
  触发器的移植没有现成工具,因为两者之间的语法差异较大,您只能通过手工对照着原来的逻辑一个一个添加。
  这里要说明一下,MySQL的SQL过程语法和Oracle PL/SQL大致相同,但还是有些细微差别:
  1. 变量声明Declare部分,在Oracle中Declare语句位于Begin之前,在MySQl中,Declare位于Begin之后;
  2. 注释不同,在Oracle中,可用 “—“ 注释一行或“/ /”注释一段,在MySQL中,需用 “/ /”或“#”来注释
  3. 对触发前后变量值的引用方法不同;在Oracle中,用 :new.eid, :old.eid表示新旧值,
  在MySQL中,用 New.eid,old.eid表示新旧值
  4. 移植中发现的问题
  1)Oracle的自治事务autonomous_transaction ,MySQL不支持,您必须用其他方式实现,MySQL不允许在触发器过程中执行对触发器所在表的操作(包括读写)
  2)MySQL函数和trigger中不能执行动态SQL语句,也就是说,您不能在触发器里面组合出来一个SQL字符串,然后用exec来执行
  3)Oracle的表级触发器,MySQL还不支持,所以必须改成使用行级触发器,注意这会导致有时SQL语句的执行效率很低
  四、存储过程,函数和程序包的移植
  程序包是Oracle用来组织逻辑功能的一个Object,MySQL不支持,因此需要将包里的存储过程﹑函数等全部放到该数据库公有过程和函数里面。

MySQL的过程和函数语法与Oracle类似,但还是有细微差别,除了数据类型需要转换,还有:
  1.格式不同,例如:
  Oracle为:
  CREATE OR REPLACE procedure procedure1(TableName in varchar2) is
  MySQL应该为:
  CREATE procedure procedure1( in TableName varchar(200))
  2.赋值语句不同:
  Oracle赋值语句为:
  strSQL := ‘update table set field1=1’;
  MySQL应该为:
  Set StrSQL = ‘update table set field1=1’;(用:=也行)
  3. 一些要用到游标的过程请注意
  MySQL过程不支持嵌套游标,不支持带参游标,不支持记录类型%ROWTYPE,不支持数组等,原Oracle用到这些的必须改写
  五、Job的移植
  Job是Oracle的定时任务实现的方法,MySQL6中用Event实现,具体语法请参考MySQL手册。
  在MySQL中使用event请注意,默认它是不运行的,您可以
  1) 保证MySQL定时任务event scheduler运行,需要MySql 5.1.6以上,并且在启动后执行SET GLOBAL event_scheduler = ON;(也可以在初始配置文件比如my.ini中加入event_scheduler = ON的参数)
  2) 启用event功能后,每次执行会往MySQL的错误日志文件写一些信息(data目录下的“主机名.err”文件),导致这个文件越来越大(除非经常做flush log操作)。所以,如果您的event执行很频繁,可在my.ini中加参数console=TRUE,这样执行event的信息就不会写进来了
  六、用户的移植
  Oracle的用户管理和MySQL下有较大区别,请分别建立用户,并赋予合适的权限。
  七、应用程序的移植
  由于语法细节上的差异,导致很多SQL语句需要改写。笔者记下了所有移植过程中碰到的SQL语句细节差异,这些也是一般项目可能会用到的地方,虽然肯定不全,但也列出来以供参考:
  1)Oracle的to_char函数不能再使用,换用如CONCAT(14.3)的形式,为了提高应用程序兼容性,建议手工写一个
  2)Oracle的to_date函数不能再使用,建议手工写一个添加到MySQL数据库
  3)Oracle的decode函数不能再使用,换用SELECT CASE 1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END 的形式
  4)nvl这样的一些专用函数,MySQL是没有的,可以把
  select nvl(to_char(num),'nothing') from t_equipment转换成
  select case num when num then num else 'nothing' end from t_equipment
  5)instr之类的函数,函数名相同,但参数个数不同
  6)Oracle的sysdate要写成sysdate()的形式
  7)包的形式已经取消,所以原来以包的方式调用的过程如xx_pack.xxx要写成xxx()
  8)带进制字符转数字
  Oracle风格:TO_NUMBER(strTmp,'XX') TO_NUMBER(’9’)
  MySQL风格:CONV(strTmp,16,10) CONV(’9’,10,10) 如果字符串前后有加减操作,会隐含转换成数字
  9) 不能再有直接调用序列的形式,如果一定需要,可以模拟实现一个
  10)日期直接加减的含义不同了,比如Oracle中sysdate + 1 变成了sysdate() + interval 1 day(注意如果写成sysdate() + 1 语法还是正确的,但含义是错误的)
  查询select sysdate() + 1 from dual 在MySQL得到比如 20080223153234(= 20080223153233 + 1)的数
  而在Oracle中会得到第二天当前时刻。
  11) MySQL单纯的date类型只是日期不带时间,DATETIME或TIMESTAMP带有时间,用DATE_FORMAT函数可以控制显示形式
  12)select 'abc' || 'd' from dual 两个数据执行的结果不同(语法都能通过),MySQL要写成selectconcat('abc' , 'd')的形式
  13) Oracle高级功能,如带有暗示索引的select语句,MySQL是不支持的(语法可以通过)
  14)有些MySQL的保留字不能直接用在SQL语句里,要加表名或别名限制,如select RIGHT FROM XX要改成select a.RIGHT FROM XX a
  15) Oracle的子查询可以不起别名,但MySQL是必须的,比如下面的别名aa:
  select field1 from (select sysdate() as field1 from dual) as aa
 16)很多系统表名都是不同的,比如,列出某个表的信息:
  select * from tab where TName='T_TEST'改成
  select table_name,table_type from information_schema.tables where table_schema = 'user' and table_name=' T_TEST '
  17)MySQL下update时不能有本身的子查询
  update T_TEST set Flag = 0 where field1 in
  (select distinct b.field1 from T_TEST b where b.flag=1)
  18)Oracle下’’和null等价,而MySQL则不然
  select 1 from dual where '' is null在Oracle下可以取到记录,在MySQL下不能
  dual表的使用,substr、trim等函数的主要使用方式和Oracle类似
  八、小结和建议
  看起来,Oracle移植到MySQL似乎挺麻烦,有没有一键完成的简单办法?呵呵,我没有找到,除非您只使用基本表,只使用基本SQL语句访问它。当然,建议大家初始设计的时侯,就考虑到多数据库的支持,权衡一下使用一些高级功能带来的好处和对可移植性方面带来的损害,这会大大减少后期移植时面对的问题;另外,在应用架构设计时,也建议使用较好的框架去屏蔽这些差异,比如J2EE的Hibernate框架等。
  感谢伟大的Oracle,给我们提供了很多的高级功能,有很多是MySQL没有的,因此,在移植时你不得不放弃一些非必须的功能,比如,全表cache﹑物化视图﹑函数索引等;如果该功能是必须的,您可能要使用别的方式来实现,或者转到应用程序层面来考虑。当然,这些功能MySQL今天没有,不代表明天也没有,我们可以拭目以待。
  由于开源软件的原因,MySQL的bug或者缺陷有时还会干扰你,请仔细测试和优化您的应用程序,调整MySQL的配置参数,确保它可以运行得和Oracle下一样好。

最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-08-19 02:24:46

Oracle数据库移植到MySQL实战的相关文章

把Oracle数据库移植到Microsoft SQL Server 7.0

oracle|server|数据|数据库  把Oracle数据库移植到Microsoft SQL Server 7.0 摘要:本文是为那些想把自己的Oracle应用程序转换为Microsoft SQL Server应用程序的开发人员编写的.本文描述了一个成功的转换所需要的工具.过程和技术.同时强调了建立高性能.高度并行的SQL Server应用程序的基本的设计要素. 本文的读者应该具有: Oracle关系型数据管理系统(RDBMS)的坚实基础. 普通数据库管理知识. 熟悉Oracle SQL和P

Oracle数据库移植时字符集问题的解决

对于Oracle数据库之间的移植采用Oracle的导入导出工具(Import/Export)是一个比较好的策略.虽也可以利用第三方软件如Sybase 的Power designer中的Reverse Engineering 进行数据库结构重建,然后在进行较复杂的数据导入过程,但对于作业队列.快照等则不得不用手工来创建.而Export能将整个数据库.指定用户.指定表和相关的数据字典进行输出,Export输出的输出转存二进制文件包括了完全重建所有被选对象所需的命令. 本人在为某电厂MIS(Oracl

spring配置ibatis oracle数据库改成mysql数据库遇到数据库方言问题

问题描述 spring配置ibatisoracle数据库改成mysql数据库遇到数据库方言问题<!--spring配置ibatis--><beanid="sqlMapClient"class="org.framework.ibatis.spring.SqlMapClientFactoryBean"><!--Mysql,Sqlserver通用ibatis配置文件-->propertyname="configLocation

MySQL数据库移植总结

一.前言 MySQL是一个由瑞典MySQL AB公司开发的关系型数据库管理系统,目前归属Oracle公司旗下.MySQL是一种关联数据库管理系统,它将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性.由于其体积小.速度快.总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择MySQL作为网站数据库. 考虑到MySQL的诸多优点,很多通讯类软件都开始采用MySQL作为其业务数据库,前期采用Oracle或Sybase的软件也启动了向MySQL数据库

Oracle移植到MySQL注意事项

客户用的数据库是mysql,而研发好的产品支持oracle,为了让客户掏腰包,我们必须把数据库环境从oracle转向mysql.我们在转换的过程中碰到了下面一些问题,希望能给同样遭遇的同仁们一些借鉴.如果我们在最初的设计.编码过程中注意数据库的移植性,这种情况下可以完全不需要作额外工作. 一.数据库环境从oracle转向mysql碰到的问题. 因为逻辑不变,所以原则是不改应用程序代码,只改数据库表的创建/初始化sql.下面是我们碰到的问题以及解决办法. 1. 大小写敏感的区别(如果服务器OS是l

把oracle数据库中的表写到mysql中

问题描述 把oracle数据库中的表写到mysql中 如题,oracle数据库中的表格,完完全全的导入到mysql数据库中,有没有什么简单的方法,不要写程序之类的.有没有大神知道?望指教. 解决方案 移植oracle数据库表结构到mysql数据库分页,Oracle 和 mysql 解决方案二: 这好像有点难吧?有些字段类型名称都不一样 解决方案三: robot已经告诉你了,数据库之间的类型啥的都不一样,不可能完全导入,必须做一些转换才行.

将MySQL数据库移植为PostgreSQL_Mysql

在北美,人们对于 PostgreSQL 的热情不断升温.随着 PostgreSQL 的发展, PostgreSQL 8.x 已经从技术上超越 MySQL 5.x ,而市场的超越相信只是时间问题.而最终,用户也许有机会享受到可媲美 Oracle 的开源数据库也未尝没有可能. 我供职的互联网公司,服务约 50 万商务用户,经过多次的升级移植,目前公司已经全部将后台数据库从 MySQL 移植到 PostgreSQL ,而个人完成了其中一半的数据库移植工作,所以对数据库从 MySQL 移植到 Postg

mysql数据库迁移至Oracle数据库_Mysql

本文实例为大家分享了java获取不同路径的方法,供大家参考,具体内容如下 1.使用工具: (1) Navicat Premium (2) PL/SQL Developer 11.0 (3) Oracle SQL Developer 4.0.0.12.84(点击可进入下载页面) 特别说明:最初我用的一直是高版本的SQL Developer,但在数据库移植到大概两分钟的时候,总是报错,而错误信息又不明确.最后换成 Oracle SQL Developer 4.0.0.12.84,才把问题解决掉!如果

用PHP连mysql和oracle数据库性能比较

mysql|oracle|比较|数据|数据库|性能 用PHP连mysql和oracle数据库性能比较 测试硬件说明:测试使用的是我的爱机,配置如下:CPU:C433内存:128M硬盘:酷鱼2代20G 测试软件说明:WIN32下用的是windows nt server4,sp5,apache 1.3.12,php3.0.15和php4rc1,mysql 3.22.29,oracle 8.0.5linux下用的是bluepoint linux1.0, apache 1.3.12, php4rc1,m