Oracle向MySQL 迁移相关事项

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Oracle向MySQL 迁移相关事项

从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语句的执行效率很低

三、存储过程的移植

MySQL的过程和函数语法与Oracle类似,但还是有细微差别,除了数据类型需要转换,还有:

1)格式不同,例如:

Oracle为:

CREATE OR REPLACE procedure procedure1(TableName in varchar2) is

MySQL应该为:

CREATE procedure procedure1( in TableNamevarchar(200))

2)赋值语句不同:

Oracle赋值语句为:

strSQL := ‘update table set field1=1’;

MySQL应该为:

Set StrSQL = ‘update table set field1=1’;(用:=也行)

四、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为ifnull,可以把

select nvl(to_char(num),'nothing') fromt_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带有时间,用

相关文档
最新文档