揪出数据库中看不见的字符

应用报出了异常,发现某表某字段下的数据多了些字符,但是在数据库中用sql查看时不一定能够发现。这种情况一般是在字符结尾多了空格、制表符、回车符、换行符等造成。可以从数据库中校验并修正这些异常数据。

基础知识

特殊字符ascii码,Oracle和MySQL中的表示方法:

特殊符号

Oracle

MySQL

TiDB

空格

chr(32)

char(32)

char(32)

制表符

chr(9)

char(9)

char(9)

回车符

chr(13)

char(13)

char(13)

换行符

chr(10)

char(10)

char(10)

更多ascii码可参考https://blog.csdn.net/u010033674/article/details/113033220

Oracle中可以用ascii函数查看对应的ascii码:

select ascii(' ') from dual;
        32
select ascii('&') from dual;
        38

MySQL中也有对应的函数:

 select ascii(' ');
+------------+
| ascii(' ') |
+------------+
|         32 |
+------------+

select ascii('&');
+------------+
| ascii('&') |
+------------+
|         38 |
+------------+

揪出问题数据

创建测试数据:

Oracle 11.2测试表:

create table test_char (
  id int,
  name varchar2(50),
  note varchar2(50)
  );

MySQL 5.7、TiDB 3.0测试表:

drop table test_char;
create table test_char (
id int,
name varchar(50),
note varchar(50)
) ;

分别在不同类型数据库中插入测试数据:

--oracle
INSERT  INTO  test_char VALUES (1,'0123456789 ','空格');  
INSERT  INTO  test_char VALUES (2,'0123456789'||chr(9),'制表符'); 
INSERT  INTO  test_char VALUES (3,'0123456789'||chr(10),'回车符');  
INSERT  INTO  test_char VALUES (4,'0123456789'||chr(13),'换行符'); 
commit;
--mysql/tidb
INSERT  INTO  test_char VALUES (1,'0123456789 ','空格');  
INSERT  INTO  test_char VALUES (2,concat('0123456789',char(9)),'制表符'); 
INSERT  INTO  test_char VALUES (3,concat('0123456789',char(10)),'回车符');  
INSERT  INTO  test_char VALUES (4,concat('0123456789',char(13)),'换行符'); 

--oracle中检查出异常数据

select id,name,length(name),note,
case when name like '% %' then '有空格'
     when name like '%'||chr(9)||'%' then '有制表符'
     when name like '%'||chr(13)||'%' then '有换行符'
     when name like '%'||chr(10)||'%' then '有回车符'
 end as chk_teshu
 from test_char;

image.png

从检查结果中可以看出,name字段中期望的是10个字符,length函数检查出来是11个字符,多了一个看不见的字符,通过like匹配,检查出对应的特殊字符。

--mysql/tidb中检查异常数据

select id,name,length(name),note,
case when name like '% %' then '有空格'
     when name like concat('%',char(9),'%') then '有制表符'
     when name like concat('%',char(13),'%') then '有换行符'
     when name like concat('%',char(10),'%') then '有回车符'
 end as chk_teshu
 from test_char;

image.png

从mysql/tidb检查结果中看到,和oracle一样,name字段中期望的是10个字符,length函数检查出来是11个字符,多了一个看不见的字符,通过like匹配,检查出对应的特殊字符。

清洗问题数据

--使用replace函数替换掉多余的特殊字符

--oracle
update test_char set name =replace(name,chr(9),'');
update test_char set name =replace(name,chr(10),'');
update test_char set name =replace(name,chr(13),'');
--mysql/tidb
update test_char set name =replace(name,char(9),'');
update test_char set name =replace(name,char(10),'');
update test_char set name =replace(name,char(13),'');

猜你喜欢

转载自blog.csdn.net/u010033674/article/details/113048621
今日推荐