数据库迁移数据转义问题:db2迁移到mysql

数据库迁移,db2迁移到mysql,运维使用的是MTK工具,具体操作不太清楚,但是出现了转义字符问题,就是在db2数据库中的数据为"\n"两个字符,导入到mysql数据库,数据变为"\n"一个字符(转为为了换行符),MTK工具能否设置不太清楚,但是可以通过曲线策略实现数据正常,步骤如下:

  1. mysql的sql_mode增加配置NO_BACKSLASH_ESCAPES(禁止转义);
  2. MTK执行数据迁移,db2迁移到mysql;
  3. mysql的sql_mode删除配置NO_BACKSLASH_ESCAPES(禁止转义);

1.转义字符【\】问题

DBeaver客户端不同数据库【mysql、db2】相同流程结果分析:

  • mysql【sql_mode不设置NO_BACKSLASH_ESCAPES(默认不设置)】:

1.DBeaver客户端执行插入语句:

INSERT INTO test(ID,NAME1,NAME2) VALUES(1, 'a\\rb\\nc','a\rb\nc\d');

2.DBeaver客户端执行查询语句:

SELECT * FROM test WHERE ID = 1;

3.DBeaver客户端查看返回结果:

IDNAME1NAME2
1a\rb\nca’\r’b’\n’cd

结果解析:
NAME1:“a\rb\nc”,字符长度为7,\r、\n各占两个字符;
NAME2:"a’\r’b’\n’cd"字符长度为6,\r转义为回车符,\n转义为换行符,\d无法转义则自动去除掉转义字符\;
mysql默认会对转义字符进行解析,会将\r、\n进行转义为单个字符,并自动去除无法进行转义的转义字符\;

4.DBeaver客户端导出数据,导出的sql如下【各个客户端导出的数据时处理回车换行符逻辑不一样】:

-- DBeaver导出sql如下:
INSERT INTO test(ID,NAME1,NAME2) VALUES(1, 'a\\rb\\nc','a
b
cd');

-- Navicat导出sql如下:
INSERT INTO test(ID,NAME1,NAME2) VALUES(1, 'a\\rb\\nc','a\rb\ncd');
  • mysql【sql_mode设置NO_BACKSLASH_ESCAPES】:
    1.Dbeaver客户端设置sql_mode为NO_BACKSLASH_ESCAPES:
-- 查询sql_mode配置
SELECT @@sql_mode;
-- 修改会话级别的sql_mode
SET SESSION sql_mode = '...,NO_BACKSLASH_ESCAPES';
-- 修改全局级别的sql_mode
SET GLOBAL sql_mode = '...,NO_BACKSLASH_ESCAPES';

2.DBeaver客户端执行插入语句:

INSERT INTO test(ID,NAME1,NAME2) VALUES(1, 'a\\rb\\nc','a\rb\nc\d');

2.DBeaver客户端执行查询语句:

SELECT * FROM test WHERE ID = 1;

3.DBeaver客户端查看返回结果:

IDNAME1NAME2
1a\\rb\\nca\rb\nc\d

结果解析:
NAME1:“a\\rb\\nc”,字符长度为9,不会对转义字符\进行任何转义,原样存储;
NAME2:"a\rb\nc\d"字符长度为9,不会对转义字符\进行任何转义,原样存储;
mysql默认会对转义字符进行解析,会将\r、\n进行转义为单个字符,并自动去除无法进行转义的转义字符\;

4.DBeaver客户端导出数据,导出的sql如下【各个客户端导出的数据时处理回车换行符逻辑不一样】:

-- DBeaver导出sql如下,在当前sql_mode:NO_BACKSLASH_ESCAPES,模式下再次执行sql会导致数据与源数据不一致,就是每次导出数据再次执行数据都会发生改变:
INSERT INTO test(ID,NAME1,NAME2) VALUES(1, 'a\\\\rb\\\\nc','a\\rb\\nc\\d');
  • db2

1.DBeaver客户端执行插入语句:

INSERT INTO test(ID,NAME1,NAME2) VALUES(1, 'a\\rb\\nc','a\rb\nc\d');

2.DBeaver客户端执行查询语句:

SELECT * FROM test WHERE ID = 1;

3.查看返回结果:

IDNAME1NAME2
1a\\rb\\nca\rb\nc\d

结果解析:
NAME1:“a\rb\nc”,字符长度为9;
NAME2:"a\rb\nc\d"字符长度为9;
db2不会对转义字符进行解析,全部按照单个字符存入数据库;

4.使用DBeaver工具导出数据,导出的sql如下【各个客户端导出的数据时处理回车换行符逻辑不一样】:

-- DBeaver导出sql如下:
INSERT INTO test(ID,NAME1,NAME2) VALUES(1, 'a\\rb\\nc','a\rb\nc\d');

java程序层面不同数据库【mysql、db2】相同流程结果分析:

1.java程序执行插入语句:

entity.setId(1);
entity.setName1("a\\rb\\nc");
entity.setName2("a\rb\nc"); // java使用转义字符\后边必须跟随能够转义的特殊字符
entityDao.insert(entity);

2.java程序执行查询语句:

entity.setId(1);
Entity entity = entityDao.query(entity);

3.查看返回结果:

IDNAME1NAME2
1a\rb\nca’\r’b’\n’c

结果解析:
NAME1:“a\rb\nc”,字符长度为7,\r、\n各占两个字符;
NAME2:"a’\r’b’\n’c"字符长度为5,\r转义为回车符,\n转义为换行符;
mysql【sql_mode不设置NO_BACKSLASH_ESCAPES(默认不设置)】、db2数据库存储的数据完全与java程序中的数据一一对应





参考链接:

  1. SQL服务器模式https://www.mysqlzh.com/doc/40/167.html
  2. SQL服务器模式官网https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值