
讲解Oracle数据库移植到MySQL
出处:IT专家网 日期:2010-06-24
一、前言
公司原来的项目是基于Oracle数据库的,Oracle功能强大,但是部署和管理较复杂,更重要的是,购买Oracle的费用不是每个客户都愿意承担的。因此,迫切需要把公司项目所用数据库移植到一个简单好用的数据库上。当然,如您所料,我们选择了广受欢迎的MySQL。
作为一个开源数据库,MySQL用无数案例证明了她的可用性,因此让我们把重点放在如何将Oracle移植到MySQL上。已经有很多的文章和专题介绍了Oracle移植到MySQL的方法和步骤,也有相当多的工具可以辅助这种移植过程。但是,由于数据库实现的差异,完美的移植工具是不存在的,移植过程中不断碰到的问题证明了这一点,特别是您使用了Oracle的一些高级特性时。
从Oracle移植到MySQL主要有六个方面的内容需要移植,一是表Table,包括表结构和数据,二是触发器Trigger,三是存储过程Procedure,函数function和包Package,四是任务Job,五是用户等其他方面的移植,六是具体应用程序通过SQL语句访问时的细节差异克服。
笔者用来移植测试的数据库是:Oracle 9i ,MySQL 60,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在60以后才支持触发器!
触发器的移植没有现成工具,因为两者之间的语法差异较大,您只能通过手工对照着原来的逻辑一个一个添加。
这里要说明一下,MySQL的SQL过程语法和Oracle PL/SQL大致相同,但还是有些细微差别:
1 变量声明Declare部分,在Oracle中Declare语句位于Begin之前,在MySQl中,Declare位于Begin之后;
2 注释不同,在Oracle中,可用 “—“ 注释一行或“/ /”注释一段,在MySQL中,需用 “/ /”或“#”来注释
3 对触发前后变量值的引用方法不同;在Oracle中,用 :neweid, :oldeid表示新旧值,
在MySQL中,用 Neweid,oldeid表示新旧值
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 516以上,并且在启动后执行SET GLOBAL event_scheduler = ON;(也可以在初始配置文件比如myini中加入event_scheduler = ON的参数)
2) 启用event功能后,每次执行会往MySQL的错误日志文件写一些信息(data目录下的“主机名err”文件),导致这个文件越来越大(除非经常做flush log *** 作)。所以,如果您的event执行很频繁,可在myini中加参数console=TRUE,这样执行event的信息就不会写进来了
六、用户的移植
Oracle的用户管理和MySQL下有较大区别,请分别建立用户,并赋予合适的权限。
七、应用程序的移植
由于语法细节上的差异,导致很多SQL语句需要改写。笔者记下了所有移植过程中碰到的SQL语句细节差异,这些也是一般项目可能会用到的地方,虽然肯定不全,但也列出来以供参考:
1)Oracle的to_char函数不能再使用,换用如CONCAT(143)的形式,为了提高应用程序兼容性,建议手工写一个
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_packxxx要写成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要写成select concat('abc' , 'd')的形式
13) Oracle高级功能,如带有暗示索引的select语句,MySQL是不支持的(语法可以通过)
14)有些MySQL的保留字不能直接用在SQL语句里,要加表名或别名限制,如select RIGHT FROM XX要改成select aRIGHT 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_schematables where table_schema = 'user' and table_name=' T_TEST '
17)MySQL下update时不能有本身的子查询
update T_TEST set Flag = 0 where field1 in
(select distinct bfield1 from T_TEST b where bflag=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下一样好。
(责任编辑:王倩)
建立一个信息库
Oracle Migration Workbench利用一个Oracle数据库架构作为移植信息库,用来储存其为移植进程所收集和转换的元数据。不管你要进行多少次移植 *** 作,建立移植信息库只需要执行一次就够了。这个信息库由37个表以及相关的主键、索引,8个视图,触发器和PL/SQL代码组成。虽然不是必须的,不过Oracle还是建议专门为这个信息库配置一个数据库架构。
必须赋予创建和拥有这个信息库的用户多种系统权限和任务。列表1创建了一个名为migration的用户,并赋予其必要的特权。
代码列表1:创建migration用户
CREATE USER migration IDENTIFIED BY migration
DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp;
GRANT CONNECT, RESOURCE, CREATE VIEW, CREATE PUBLIC SYNONYM
TO migration WITH ADMIN OPTION;
GRANT ALTER ANY ROLE, ALTER ANY SEQUENCE,
ALTER ANY TABLE, ALTER TABLESPACE, ALTER ANY TRIGGER,
COMMENT ANY TABLE, CREATE ANY SEQUENCE, CREATE ANY TABLE,
CREATE ANY TRIGGER, CREATE ROLE, CREATE TABLESPACE,
CREATE USER, DROP ANY SEQUENCE, DROP ANY TABLE,
DROP ANY TRIGGER, DROP TABLESPACE, DROP USER,
DROP ANY ROLE, GRANT ANY ROLE, INSERT ANY TABLE,
SELECT ANY TABLE, UPDATE ANY TABLE
TO migration;
一旦你创建了这个用户,你就需要为这个用户建立一个新的数据库连接,例如Migration_Repos。当你输入必要的信息之后,点击Connect保存连接并关闭对话框。从主菜单中选择Migration -> Repository Management -> Create Repository。选择为新信息库建立的连接,并点击Create。这时,会出现一个Installing Repository对话框,显示安装进度。当进程结束后,关闭对话框。
在Connections Navigator下会d出两个额外的窗口,显示捕获和转换模式。
数据移植到Oracle数据库第3部分:(电脑编程网整理,请尊重作者权益,转载注明出处;)
移植
整个移植过程包括几个独立的步骤。当你已经连接到移植的目标数据库并创建了信息库之后,就可以按照以下的程序进行移植了:
1、 捕获源数据库
2、 转换捕获的数据库
3、 为新Orecle架构对象生成DDL脚本
4、 运行已生成的DDL脚本以创建新的用户和对象。
5、 如果要进行快速移植(Quick Migration),就将源数据库的任何数据复制到新的数据库。Oracle SQL Developer也提供快速移植的功能。这个向导驱动的方法能够把架构和数据移植到Oracle数据库,并支持最小权限移植,即用户可以在不需要DBA权限的情况下将他们访问的源数据库对象移植到目标数据库。不需要用户插手,快速移植向导就可以自己完成整个移植过程。
从主菜单中选择Migration -> Quick Migrate,以调用Quick Migration选项。向导会提供一个对话框,让你选择源连接(与第三方数据库的连接)和目标连接(与Oracle的连接)。向导会检测你是否有可用的信息库,如果没有,它会在移植过程中创建一个。一旦移植完成,你同样可以选择保存还是删除这个信息库。点击Verify以连接第三方数据库和Oracle数据库,并验证已经赋予Oracle数据库中的架构必要的权限。验证完毕后,点击Migrate完成快速移植。
移植指南。使用以下的移植指南,你可以更加得心应手地掌控整个移植过程,并能够选择单个的表或架构对象进行移植。你还能够在移植过程的不同阶段随时进行更新,例如对架构进行重命名,在表被捕获后而被转换成Oracle模式前对其进行取消或重命名等 *** 作。我们还是按部就班一个一个来:
步骤一:捕获源数据库。右击Connections Navigator中的源数据库连接节点,选择Capture Microsoft SQL Server。会d出一个进度对话框,显示捕获过程的进度。显示完成时,点击Close,关闭对话框。源数据库被捕获后,元数据定义就储存在移植信息库中,随时都可以进行转换。Captured Objects窗口中将显示可用的捕获数据库。展开新的节点,浏览输出结果。这时候,你可以进行任何诸如对表进行重命名等修改 *** 作。
步骤二:转化捕获的数据库。如果你对第一步的结果没有任何疑问了,就右击新近捕获的模型,选择Convert to Oracle Model。这时,会d出一个数据图供你选择接受或修改。点击Apply选择默认设置。接着会d出一个进度对话框,当显示转化过程完成时,点击Close关闭对话框。捕获模型和转换模型都映射储存在移植信息库中的元数据。
从服务器将ORACLE数据库导出和导入本地oracle数据库中的方法一:将服务器上的ORACLE数据库导入到本地机子上;
具体方法:
在CMD模式下执行以下命令
exp username/password@服务器端数据库ID file=c:/文件名dmp
例如下面:
exp djyy/djyy@zhwx file=c:/djyy20090921dmp
exp wxzd/wxzd@zhwx file=c:/wxzd20090921dmp
二:建立本地oracle数据库
具体方法:
点击开始->程序->Oracle - OraDb10g_home1->配置和移植工具->Database Configuration Assistant
运行后点击下一步,选择创建数据库->next->选择一般用途->填写自己的数据库名->next-->填写口令,选择同一口令吧,当然你也可以为每个用户填写不同的口令,以后基本上默认安装吧。安装完成后退出即可。
三:建立用户,并赋予DBA权限
具体方法:
在刚建立的本地数据库中,用DBA的权限账户进入,然后建立自己的用户,并赋予DBA等权限;
具体实例代码:
1 SQL> conn sys/change_on_install as sysdba;
2 已连接。
3 SQL> create user username identified by password;
4 users;
5
6 用户已创建。
7 SQL> grant create session,create table,create view to username
8 授权成功。
9 SQL>grant DBA to uername;
10 授权成功。
四:导入oracle数据库
具体方法:
在CMD模式下执行以下命令
imp 用户/密码 file=dmp commit=y full=y
以上就是关于如何配置oracle数据库环境全部的内容,包括:如何配置oracle数据库环境、如何用oracle的配置和移植工具连接数据库、如何将oracle数据库转换成mysql数据库,现在公司有急用,方法可用的话再加分!等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)