热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Oracle到MySQL的迁移步骤及各种注意事项

最近公司一个项目需要将数据库进行一次迁移,从Oracle到mysql,网上资料甚少,现将我本次迁移过程中所遇到的一些问题总结于此(主

最近公司一个项目需要将数据库进行一次迁移,从Oracle到mysql,网上资料甚少,现将我本次迁移过程中所遇到的一些问题总结于此(主

最近公司一个项目需要将数据库进行一次迁移,从Oracle到mysql,网上资料甚少,现将我本次迁移过程中所遇到的一些问题总结于此(主要是存储过程的迁移),希望能给自己做一个日后的参考,如果有幸能帮助到大家更好。

-- mysql中没有包的概念,因此迁移的时候将存储过程命名为'包名.存储过程名'的格式

mysql存储过程格式:

DELIMITER $$ -- 分隔符

-- CREATE PROCEDURE([[IN |OUT ] 参数名 数据类型...]) ,IN和OUT写在最前面,其中IN可以省略

CREATE PROCEDURE `pkg_ypgl.prc_ypsc`(

prm_ypbm VARCHAR (20),

OUT prm_AppCode VARCHAR (20),

-- 程序执行代码

OUT prm_ErrorMsg VARCHAR (100)

-- 程序执行错误信息

)

BEGIN

/*变量定义*/

DECLARE n_count DECIMAL (8) ;

DECLARE done INT(10);

/*设置游标结束标志*/

DECLARE CONTINUE HANDLER FOR NOT FOUND SET dOne=1; -- 如果NOT FOUND,取不到值,则将done赋值1,并且程序继续执行

SET dOne=0;

/*定义一个区块lavel_error,逻辑错误处理*/

label_error : BEGIN

/*定义游标*/

DECLARE cur_bdjl CURSOR FOR

SELECT .....

/*打开游标*/

OPEN cur_bdjl ;

REPEAT

FETCH cur_bdjl INTO v_aaz001....

IF NOT done THEN -- 如果结束标志done为0则继续循环

........

END IF;

/*结束循环,关闭游标*/

UNTIL done -- 直到NOT FOUND

END REPEAT ;

CLOSE cur_bdjl ;

SET prm_AppCode = 'noerror' ; -- 将prm_AppCode设为正确

SET prm_ErrorMsg = '' ;

END;

END$$

DELIMITER ;

数据类型:

Oracle:varchar2 Mysql:varchar(20) (参数自设)

Oracle:number() Mysql:decimal()

Oracle:date Mysql:datetime

定义变量:

Mysql需要在每句前面加DECLARE

给变量赋值:

Oracle:v_string := ‘asdas’; Mysql: SET string := ‘asdas’; (等号前面的冒号可以有也可以没有)

异常处理:

Oracle:EXCEPTION WHEN OTHERS THEN….

Mysql: DECLARE { EXIT | CONTINUE } HANDLERFOR { error-number | { SQLSTATE error-string } | condition } SQL statement;

SQLWARNING 代表所有以01开头的错误代码

NOT FOUND 代表所有以02开头的错误代码,也包括游标结束的时候

SQLEXCEPTION 代表除了SQLWARNING和NOT FOUND 的所有错误代码

eg. DECLARE EXIT HANDLER FORSQLEXCEPTION,SQLWARNING,NOT FOUND SET a = 1;

注:一个begin....end里面只能声明一个HANDLER,,EXIT表示遇到这种异常时就执行SET a = 1然后结束这个存储过程,CONTINUE表示遇到这种异常时就SET a = 1,然后继续执行之后的存储过程

跳转:

Oracle: GOTO label_error;

…..

<>

Mysql:初始化错误代码prm_AppCode为“错误”,定义一个区块label_error,在区块的最后将prm_AppCode set为’noerror’,中间触发条件,将GOTO label_error;改写成leave label_error;跳出区块

游标:

Mysql只有静态游标,没有动态游标,用存储过程代替

定义游标的语句为DECLAREcur_bdjl CURSOR FOR …..

Mysql不支持rec_curname.aaz001这种写法,所以必须将游标取得的所有字段FETCH INTO 到变量里

循环:

Mysql里有三种循环方式

(1).WHILE循环

WHILE expression DO

statements

END WHILE;

(2).LOOP循环

LOOP

statements

END LOOP;

(3).REPEAT UNTIL循环

REPEAT

statements

UNTIL expression

END REPEAT;

序列:

Mysql中没有序列,用函数+表的方法取代.

建表语句:

CREATE TABLE `seq` (
`name` varchar(20) NOT NULL DEFAULT '' COMMENT '序列号生成器名称',
`val` bigint(20) unsigned NOT NULL COMMENT '序列号',
`increment` int(4) DEFAULT '1' COMMENT '序列的增量',
`min` bigint(20) DEFAULT NULL COMMENT '序列最小值',
`max` bigint(20) DEFAULT NULL COMMENT '序列最大值',
`cycle` char(1) DEFAULT 'N' COMMENT '是否循环',
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='mysql模拟序列号生成器用表'

函数如下(自己写的,可能有错):

DELIMITER $$

DROP FUNCTION IF EXISTS `seq`$$

CREATE FUNCTION `seq`(seq_name VARCHAR(20))RETURNS BIGINT(20)

BEGIN

DECLARE v_value BIGINT(20);

DECLARE v_CYCLE CHAR;

DECLARE v_MIN BIGINT(20);

DECLARE v_MAX BIGINT(20);

SELECT a.val,a.MIN,a.MAX,a.CYCLE INTOv_value,v_MIN,v_MAX,v_CYCLE FROM seq a WHERE NAME = seq_name;

IFv_CYCLE = 'Y' AND v_value = v_MAX THEN -- 该序列为循环且当前值为其最大值

UPDATE seq -- 将当前值设为 v_MIN

SET val = v_MIN

WHERE NAME = seq_name;

ELSE

UPDATE seq -- 否则将当前值设为val + increment

SET val = val + increment

WHERE NAME = seq_name;

END IF;

SELECT val INTO v_value FROM seqWHERE NAME = seq_name;

RETURN v_value;

END$$

DELIMITER ;

更新:

Oracle: UPDATE TABLE T SET (A,B,C) = (SELECT A,B,C FROM TABLE_2 K WHERE K.Y =T.Y) WHERE T.X = V_X;

Mysql: UPDATE TABLE T,TABLE_2 K SET T.A =K.A,T.B=K.B,T.C=K.C WHERE K.Y = T.Y ANDT.X = V_X

GROUP BY:

mysql的group by 语句可以select 没有被分组的字段,如

select id,name,age from A group by age

这个取出的id,name所在的行是每个分组中的第一行数据

调用:

Mysql:

跳出循环:

Oracle: EXIT;

Mysql: 将循环的内容定义为一个区块label_loop,需要跳出循环时则 leave label_loop;

注释:

1、#注释内容

2、-- 注释内容 注意-- 后需要加一个空格

3、块注释用/*注释内容*/

表的注释:

在oracle中执行如下语句:

table_nameCOMMENTSUSER_TAB_COMMENTS

将得到的结果放到mysql中执行即可添加表名的注释

表的字段注释:

在oracle中执行如下语句:

data_type

将查询出的本次转换涉及到的数据类型用decode函数转换为Mysql中对应函数(参数)的形式,如将CHAR转换为CHAR(20),参数的值在all_tab_columns的DATA_LENGTH DATA_PRECISION DATA_SCALE中取得。

在oracle中执行如下语句,注意decode函数里的参数需根据上一步的查询结果转换:

a.table_namea.column_nameb.data_typeb.DATA_LENGTHb.DATA_PRECISIONb.DATA_SCALEb.DATA_LENGTHcomments

from user_col_comments a,all_tab_columns b

and a.table_name = b.table_name

and a.column_name = b.column_name

将得到的结果放到mysql中执行即可添加表字段的注释

函数:

功能 oracle mysql 备注 eg.oracle eg.mysql

连接字符串 || concat() 'a'||'b'||'c' concat( 'a','b','c')

将其他格式转换为字符串 concat(x,'')

截取字符串 substr() substring() substr('abcd',1,3) substring('abcd',1,3)

string转换为date to_date() str_to_date(str, format) to_date(aae036,'yyyy-mm-dd hh24:mi:ss') str_to_date(aae036,'%Y-%m-%d %H:%i:%s')

获取当前日期 sysdate now(),sysdate(),current_date now()返回的是程序开始执行时的时间,sysdate()返回实时时间,
一般用now()
current_date表示当前的年月日

取出日期的指定部分 date_format(date,type) %Y:年
%c:月
%d:日
%H:小时
%i:分钟
%s:秒 date_format(now(),'%Y-%c-%d %h:%i:%s')

增加一天 sysdate+1 DATE_ADD(date,INTERVAL expr type) sysdate+1 DATE_ADD(now() ,INTERVAL 1 DAY)

推荐阅读
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 推荐一个ASP的内容管理框架(ASP Nuke)的优势和适用场景
    本文推荐了一个ASP的内容管理框架ASP Nuke,并介绍了其主要功能和特点。ASP Nuke支持文章新闻管理、投票、论坛等主要内容,并可以自定义模块。最新版本为0.8,虽然目前仍处于Alpha状态,但作者表示会继续更新完善。文章还分析了使用ASP的原因,包括ASP相对较小、易于部署和较简单等优势,适用于建立门户、网站的组织和小公司等场景。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了如何在MySQL中将零值替换为先前的非零值的方法,包括使用内联查询和更新查询。同时还提供了选择正确值的方法。 ... [详细]
  • 在数据分析工作中,我们通常会遇到这样的问题,一个业务部门由若干业务组构成,需要筛选出每个业务组里业绩前N名的业务员。这其实是一个分组排序的 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • Python字典推导式及循环列表生成字典方法
    本文介绍了Python中使用字典推导式和循环列表生成字典的方法,包括通过循环列表生成相应的字典,并给出了执行结果。详细讲解了代码实现过程。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • “你永远都不知道明天和‘公司的意外’哪个先来。”疫情期间,这是我们最战战兢兢的心情。但是显然,有些人体会不了。这份行业数据,让笔者“柠檬” ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
author-avatar
mobiledu2502898167
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有