如何实现国产化数据迁移的最佳方案?

2026-05-05 20:101阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1663个文字,预计阅读时间需要7分钟。

如何实现国产化数据迁移的最佳方案?

国产数据库迁移+存储过程处理+常用SQL语法比较+1. 字符串拼接+例如+Oracle中某段字符串拼接如下:+v_str :=substr(v_resource_ids, 1, instr(v_resource_ids, ',', resource_id, ','))||subs+。

国产化数据迁移 存储过程处理以及常用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 值。 详细解释请参照博客: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;跳出区块,执行区块以后的代码

关于存储过程不错的博客: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中NAMEISNULL

在mysql中 NAME=''

1.10 like的⽤法

NAMElike'a%'

在oracle中 NAMElike'a%'⼤⼩写敏感,只查询以⼩写字母a

在mysql中⼤⼩写不敏感,查询以⼩写字母a或⼤写字母A

1.11 字段类型替换

ORACLEMYSQL

VARCHAR2 VARCHAR

DATE DATETIME

TIMESTAMP DATETIME

NUMBER DECIMAL

INTEGER DECIMAL(22,0)

CLOB TEXT

BLOB LONGBLOB

1.12 分页不同

oracle中

SELECTT2.*FROM(SELECTT1.*,ROWNUMRNFROM(SELECT*FROMTESTORDERBYSIDDESC)T1WHEREROWNUM<5)T2WHERERN>=1

mysql中SELECT*FROMTEST_TEST1ORDERBYSIDDESCLIMIT0,4

1.13 分组函数

oracle中Select后⾯的列必须是分组的列或者是⽤了聚合函数的列

1.14 mysql不支持的特定函数

比方说mysql不支持

row_number()over(partition

byxxorderbyxx)

rank()over(partitionbyxx

orderbyxx)

dense_rank()over(partitionby

xxorderbyxx)

count(1)over()

1.14 改写关联+ JOIN

OracleSQL里有大量的(+),需要改写

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备份老数据迁移至中间数据库再采用中间数据库导入至新数据库

这里需要控制好缓存大小,防止进程崩了。

本文共计1663个文字,预计阅读时间需要7分钟。

如何实现国产化数据迁移的最佳方案?

国产数据库迁移+存储过程处理+常用SQL语法比较+1. 字符串拼接+例如+Oracle中某段字符串拼接如下:+v_str :=substr(v_resource_ids, 1, instr(v_resource_ids, ',', resource_id, ','))||subs+。

国产化数据迁移 存储过程处理以及常用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 值。 详细解释请参照博客: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;跳出区块,执行区块以后的代码

关于存储过程不错的博客: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中NAMEISNULL

在mysql中 NAME=''

1.10 like的⽤法

NAMElike'a%'

在oracle中 NAMElike'a%'⼤⼩写敏感,只查询以⼩写字母a

在mysql中⼤⼩写不敏感,查询以⼩写字母a或⼤写字母A

1.11 字段类型替换

ORACLEMYSQL

VARCHAR2 VARCHAR

DATE DATETIME

TIMESTAMP DATETIME

NUMBER DECIMAL

INTEGER DECIMAL(22,0)

CLOB TEXT

BLOB LONGBLOB

1.12 分页不同

oracle中

SELECTT2.*FROM(SELECTT1.*,ROWNUMRNFROM(SELECT*FROMTESTORDERBYSIDDESC)T1WHEREROWNUM<5)T2WHERERN>=1

mysql中SELECT*FROMTEST_TEST1ORDERBYSIDDESCLIMIT0,4

1.13 分组函数

oracle中Select后⾯的列必须是分组的列或者是⽤了聚合函数的列

1.14 mysql不支持的特定函数

比方说mysql不支持

row_number()over(partition

byxxorderbyxx)

rank()over(partitionbyxx

orderbyxx)

dense_rank()over(partitionby

xxorderbyxx)

count(1)over()

1.14 改写关联+ JOIN

OracleSQL里有大量的(+),需要改写

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备份老数据迁移至中间数据库再采用中间数据库导入至新数据库

这里需要控制好缓存大小,防止进程崩了。