循环执行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;
…..
<<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: call procedure_name(全部参数);
跳出循环:
Oracle: EXIT;
Mysql: 将循环的内容定义为一个区块label_loop,须要跳出循环时则 leave label_loop;
注释:
1、#注释内容
2、-- 注释内容 注意-- 后须要加一个空格
3、块注释用/*注释内容*/
表的注释:
在oracle中执行如下语句:
select 'altertable '||table_name||' comment'||' '''||COMMENTS||' '''||';'fromUSER_TAB_COMMENTS where commentsis not null;
将失掉的结果放到mysql中执行即可添加表名的注释
表的字段注释:
在oracle中执行如下语句:
select distinct(data_type) FROM all_tab_columns where owner='YDMIS'
将查询出的本次转换涉及到的数据类型用decode函数转换为Mysql中对应函数(参数)的形式,如将CHAR转换为CHAR(20),参数的值在all_tab_columns的DATA_LENGTH DATA_PRECISION DATA_SCALE中获得。
在oracle中执行如下语句,注意decode函数里的参数需根据上一步的查询结果转换:
爱,有的时候不须要山盟海誓的承诺,但她一定须要细致入微的关怀与问候;爱,有的时候不须要梁祝化蝶的悲壮,但她一定须要心有灵犀的默契与投合;爱,有的时候不须要雄飞雌从的追随,但她一定须要相濡以沫的支持与理解。
select 'alter table '||a.table_name||' modify column '||a.column_name||' '||decode(b.data_type,'VARCHAR2','VARCHAR('||b.DATA_LENGTH||')','DATE','DATETIME','NUMBER','DECIMAL('||b.DATA_PRECISION||','||b.DATA_SCALE||')','CHAR','CHAR('||b.DATA_LENGTH||')','LONGRAW','mediumblob')||' comment '||''''||comments||''''||';'
from user_col_comments a,all_tab_columns b
where a.comments is not null
and a.table_name = b.table_name
and a.column_name = b.column_name
and b.owner = 'YDMIS';
将失掉的结果放到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) | |
类型转换 |
TO_CHAR TO_DATE TO_NUMBER |
cast(xxx as type) |
type:二进制 : BINARY 字符型,可带参数 : CHAR() 日期 : DATE 时光: TIME 日期时光型 : DATETIME 浮点数 : DECIMAL 整数 : SIGNED 无符号整数 : UNSIGNED |
to_char(33) | cast(33 as char(2)) |
精度转换 | to_number(x,type) | round(x,d) |
保存到小数点后d位,而第d位的保存方式为四舍五入。若要保存x值小数点左边的d位,可将d设为负值 |
||
替换空值 | NVL( string1, replace_with) | ifnull(string1, replace_with) | |||
decode() | decode (expression, search_1, result_1, default) | case expression when search_1 then result_1 else default end |
文章结束给大家分享下程序员的一些笑话语录: 这个世界上只有10种人:懂得二进制的和不懂得二进制的。
循环执行oracle到mysql的迁移步骤及各种注意事项相关推荐
- mysql数据迁移 脚本_PHP将数据从Oracle向Mysql数据迁移实例
为什么要迁移? 首先从运营成本考虑,用Mysql可以节约不少的费用.另一方面,Mysql的稳定性及功能不断地提高与增强,基本上可以满足客户的需求,如支持多 节点部署,数据分区等.还有就是Mysql使用 ...
- oracle 向mysql数据迁移
为什么要迁移? 首先从运营成本考虑,用Mysql可以节约不少的费用.另一方面,Mysql的稳定性及功能不断地提高与增强,基本上可以满足客户的需求,如支持多 节点部署,数据分区等.还有就是Mysql ...
- qt同时连接oracle和mysql_QT连接Oracle和Mysql的详细步骤,已成功~!
近几天一直在整QT的数据库连接这一块.因为QT是开源的,所以涉及的连接Oracle及Mysql的驱动都必须自己编译生成.通过不断的测试.调试,终于把QT连接Oracle和Mysql的驱动编译生成好了. ...
- 去O入云的探索--Oracle到MySQL的迁移改造方案
,点击上方"蓝字" 关注我们,享更多干货! 1.表结构改造 数据类型映射关系 字段映射关系请参考: https://blog.csdn.net/weixin_34128839/ar ...
- mysql函数移植到oracle,oracle到mysql的迁移,函数部分
to_date(?, 'YYYY-MM-DD HH24:MI:SS')" STR_TO_DATE('2003-15-10 00:00:00','%Y-%m-%d %H:%i:%s'); ...
- mysql事件循环执行,Node.js MySQL连接,查询顺序和事件循环
Let's see this example conn.query('SET @v = 1;', (err) => { conn.query('SELECT @v;', (err, res) = ...
- oracle 迁库 教程,Oracle整库文件迁移步骤详解教程
oracle双机发生切换,客户端也连接不上,原因未知,从主机上看是虚拟内存不够,整机都是在跑oracle,看情形应该从oracle上找原因. 远程连接过去之后,从alter.log发现由于磁盘空间不足 ...
- oracle to mysql demo_oracle to mysql
http://blog.csdn.net/hwhua1986/article/details/53257427 oracle到mysql的迁移步骤及各种注意事项 http://www.2cto.com ...
- oracle实现mysql的if_【原创】ORACLE的几个函数在MYSQL里面的简单实现
david_yeung关注1人评论652人阅读2012-08-13 12:02:55 最忌在做ORACLE到MYSQL得迁移,以下我写了三个简单的MYSQL里面米有的函数. 供大家参考. 判断是否为时 ...
最新文章
- 静态路由和浮动路由的配置
- Android游戏开发指南一背景地图
- 基于消息机制的万能框架
- SQL Server 字符串操作
- 【JUC并发编程06】多线程锁 (公平锁和非公平锁,死锁,可重锁)
- linux下.a/.so/.la目标库区别
- 尤雨溪介绍 Vue 3:语法不变、TS 支持很好、2.0 系列还会发一个版本
- Mysql更新数据库数据sql_一条更新SQL在MySQL数据库中是如何执行的
- java并发常量_Java并发编程-常量对象(七)
- Spark 解析 : DAGScheduler中的DAG划分与提交
- time clock getrusage clock_gettime gettimeofday timespec_get 对比
- 光缆成端接头的含义是指
- java并发编程 Lock
- 高等代数---多项式
- 最简单的Python爬虫案例,看得懂说明你已入门,附赠教程
- 软件开发的流程和常用模式
- 模块化机房建设指导书_模块化机房建设方案.doc
- web前端开发常用的几种图片格式及其使用规范
- 在边缘试探的滴滴顺风车 凭什么在2019年再上线?
- Mysql查询当天,本周,本月所有数据记录