国产化数据迁移
一、存储过程处理 以及常用sql语法比较
1.1 字符串拼接
例如Oracle中某段字符创拼接如下:
v_str := substr(v_resource_ids,1,
instr(v_resource_ids, ',' || resource_id || ',')) ||
substr(v_resource_ids,
instr(v_resource_ids, ',' || resource_id || ',') +
length(',' || resource_id || ','));
到Mysql中修改为如下
set v_str = concat_ws(substr(v_resource_ids,1,
instr(v_resource_ids, concat_ws(',' , resource_id , ','))) ,
substr(v_resource_ids,
instr(v_resource_ids, concat_ws(',' , resource_id , ',')) +
length(concat_ws(',' , resource_id , ','))));
使用方法: CONCAT(str1,str2,…)
返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。
使用方法:CONCAT_WS(separator,str1,str2,...)
CONCAT_WS() 代表 CONCAT With Separator ,是CONCAT()的特殊形式。第一个参数是其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它参数。
注意:
如果分隔符为 NULL,则结果为 NULL。函数会忽略任何分隔符参数后的 NULL 值。 详细解释请参照博客:http://blog.163.com/yang_jianli/blog/static/16199000620110135214700/
1.2 显示记录的行数
在Oracle中这样表示即可:
SELECT nsrsbh from ctais_dj_nsrxx where rownum < 40 order by nsrsbh asc;
在Mysql中如下表示即可:
select nsrsbh from ctais_dj_nsrxx where @num < 40 order by nsrsbh asc;
1.3 返回值
在Oracle中如下表示
ret_str :='';
if fpmxdzstr is null then
ret_str:='';
return;
end if;
v_temp :=fpmxdzstr;
在Mysql中这样表示
lable:begin
set ret_str ='';
if fpmxdzstr is null then
set ret_str ='';
leave lable;
end if;
set v_temp :=fpmxdzstr;
end lable;
注意
也可以给区块起别名,如:lable:begin...........end lable;可以用leave lable;跳出区块,执行区块以后的代码
关于存储过程不错的博客:http://blog.csdn.net/lpz283929516/article/details/4386258
1.4 循环
例如在Oracle中循环用 while ...loop...end loop
在Mysql中则用while...do...end while
1.5 序列
在oracle中有序列,但在mysql使用 Auto_increment
BEGIN
declare t_id varchar(100);
set t_id = substr((select max(id) from report_compare_list),8);
select t_id;
END
1.6 删除语句的表别名
在oracle中删除一条语句的时候,我可以给表起别名,如下所示:
delete from ABC a where a.id=id;
在MySQL中删除一条语句的时候,不能给表起别名,否则会出错,语句如下:
delete from ABCwhereid=i.id;
如果想给表起别名也可以,如下书写
deletea from ABC awhere a.id=id;
1.7 if...else...elsif...end if
在Oracle中:if...else...elsif...end if
在MySQL中:if...else...elseif...end if
1.8 now(),sysdate
在oracle中获取当前时间用sysdate
:SYSDATE() 格式化⽇期:TO_CHAR、TO_DATE
在mysql中获取当前时间用now()
:now() 格式化⽇期 :str_to_date、date_format
1.9 空字符的判断
在oracle中NAME IS NULL
在mysql中 NAME=' '
1.10 like的⽤法
NAME like 'a%'
在oracle中 NAME like 'a%' ⼤⼩写敏感,只查询以⼩写字母a
在mysql中⼤⼩写不敏感,查询以⼩写字母a或⼤写字母A
1.11 字段类型替换
ORACLE MYSQL
VARCHAR2 VARCHAR
DATE DATETIME
TIMESTAMP DATETIME
NUMBER DECIMAL
INTEGER DECIMAL(22,0)
CLOB TEXT
BLOB LONGBLOB
1.12 分页不同
oracle中
SELECT T2.* FROM (SELECT T1.*, ROWNUM RN FROM (SELECT * FROM TEST ORDER BY SID DESC) T1 WHERE ROWNUM < 5) T2 WHERE RN >= 1
mysql中 SELECT * FROM TEST_TEST1 ORDER BY SID DESC LIMIT 0,4
1.13 分组函数
oracle中 Select 后⾯的列必须是分组的列或者是⽤了聚合函数的列
1.14 mysql不支持的特定函数
比方说mysql不支持
row_number() over (partition
by xx order by xx)
rank() over (partition by xx
order by xx)
dense_rank() over (partition by
xx order by xx)
count(1) over()
1.14 改写关联+ JOIN
Oracle SQL里有大量的(+),需要改写
1.15 表情和特殊字符
在Oracle里我们一般都选择AL32UTF8的字符集,已经可以支付生僻字和emoji的表情了,因为在迁移的时候有的表包含了大量的表情字符,在MySQL里设置了为utf8却不行,导过去之后所有的都是问号,后来改成了utf8mb4才解决问题,所以推荐默认就把所有的DB都装成utf8mb4
二、存储过程替代重构
存储过程大部分可以用shell改写,或者改成对应Java代码块
首先微粒化模块,考虑老代码细化,防止代码遗漏,建议单个功能的迁移重构替代;
其次,做好数据和代码的备份,防止意外发生时,不会对原系统产生影响;
其次,先做边缘功能重构,再核心功能优化;
最后,单一原则,可能在迁移时,尽量少的需求变更。复现原功能后再优化,防止细节处出现问题,其他关联模块雪崩;
三、数据迁移
3.1 使用navicat工具做数据迁移
打开navicat工具。分别连接MySQL 数据库和Oracle数据库。
点击工具选择数据传输,注意;如果是从Oracle到MySQL,就选中Oracle库,然后在使用数据传输,这个是传输和被传输的关系
点击开始即可完成数据迁移
3.2使用工具DBMover 的OracleToMySQL 进行导入
试用版的限制是:允许迁移的记录条数累计为10万条
3.3使用工具intelligent-converters 的 oracle-to-mysql 进行导入
3.4 不使用工具,可以采用csv备份老数据,迁移至中间数据库,再采用中间数据库导入至新数据库
这里需要控制好缓存大小,防止进程崩了。