项目做好了,更高的要求被提出来,比如,要多数据库支持,怎么办?移植!有没有人做过这事,我好参考一下?哦,这有一个…
一、前言
公司原来的项目是基于Oracle数据库的,Oracle功能强大,但是部署和管理较复杂,更重要的是,购买Oracle的费用不是每个客户都愿意承担的。因此,迫切需要把公司项目所用数据库移植到一个简单好用的数据库上。当然,如您所料,我们选择了广受欢迎的MySQL。
作为一个开源数据库,MySQL用无数案例证明了她的可用性,因此让我们把重点放在如何将Oracle移植到MySQL上。已经有很多的文章和专题介绍了Oracle移植到MySQL的方法和步骤,也有相当多的工具可以辅助这种移植过程。但是,由于数据库实现的差异,完美的移植工具是不存在的,移植过程中不断碰到的问题证明了这一点,特别是您使用了Oracle的一些高级特性时。
从Oracle移植到MySQL主要有六个方面的内容需要移植,一是表Table,包括表结构和数据,二是触发器Trigger,三是存储过程Procedure,函数function和包Package,四是任务Job,五是用户等其他方面的移植,六是具体应用程序通过SQL语句访问时的细节差异克服。
二、表的移植
这个部分的移植是最容易用工具实现的部分,因为很多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不支持,因此需要将包里的存储过程﹑函数等全部放到该数据库公有过程和函数里面。