139

我正在使用一个 MySQL 数据库,该数据库具有从Excel导入的一些数据。数据包含非ASCII字符(短划线等)以及隐藏的回车符或换行符。有没有办法使用 MySQL 找到这些记录?

4

10 回答 10

281

MySQL 提供了全面的字符集管理,可以帮助解决这类问题。

SELECT whatever
  FROM tableName 
 WHERE columnToCheck <> CONVERT(columnToCheck USING ASCII)

CONVERT(col USING charset)函数将不可转换的字符转换为替换字符。然后,转换和未转换的文本将不相等。

有关更多讨论,请参阅此内容。https://dev.mysql.com/doc/refman/8.0/en/charset-repertoire.html

您可以使用任何您希望的字符集名称来代替 ASCII。例如,如果您想找出代码页 1257(立陶宛语、拉脱维亚语、爱沙尼亚语)中哪些字符无法正确呈现,请使用CONVERT(columnToCheck USING cp1257)

于 2012-07-31T13:33:13.093 回答
92

您可以将 ASCII 定义为十进制值为 0 - 127 (0x00 - 0x7F) 的所有字符,并使用以下查询查找具有非 ASCII 字符的列

SELECT * FROM TABLE WHERE NOT HEX(COLUMN) REGEXP '^([0-7][0-9A-F])*$';

这是我能想到的最全面的查询。

于 2009-08-09T22:58:56.417 回答
72

这完全取决于您定义为“ASCII”的内容,但我建议尝试如下查询的变体:

SELECT * FROM tableName WHERE columnToCheck NOT REGEXP '[A-Za-z0-9]';

该查询将返回 columnToCheck 包含任何非字母数字字符的所有行。如果您有其他可接受的字符,请将它们添加到正则表达式中的字符类。例如,如果句点、逗号和连字符都可以,则将查询更改为:

SELECT * FROM tableName WHERE columnToCheck NOT REGEXP '[A-Za-z0-9.,-]';

MySQL 文档中最相关的页面可能是12.5.2 正则表达式

于 2008-12-30T23:19:12.143 回答
50

这可能是您正在寻找的:

select * from TABLE where COLUMN regexp '[^ -~]';

它应该返回 COLUMN 包含非 ASCII 字符(或不可打印的 ASCII 字符,例如换行符)的所有行。

于 2009-03-12T16:00:08.493 回答
15

上述每个人的示例中缺少的一个字符是终止字符 (\0)。这对 MySQL 控制台输出是不可见的,并且不能被之前提到的任何查询发现。查找它的查询很简单:

select * from TABLE where COLUMN like '%\0%';
于 2013-08-26T20:22:18.977 回答
4

基于正确答案,但也考虑到 ASCII 控制字符,对我有用的解决方案是:

SELECT * FROM `table` WHERE NOT `field` REGEXP  "[\\x00-\\xFF]|^$";

它做同样的事情:在列中搜索违反 ASCII 范围的情况,但也允许您搜索控制字符,因为它使用十六进制表示法作为代码点。由于没有比较或转换(与@Ollie 的答案不同),这也应该更快。(特别是如果 MySQL 提前终止正则表达式查询,它肯定应该这样做。)

它还避免返回长度为零的字段。如果您想要一个可能性能更好的稍长版本,您可以使用它来代替:

SELECT * FROM `table` WHERE `field` <> "" AND NOT `field` REGEXP  "[\\x00-\\xFF]";

它会单独检查长度以避免零长度结果,而不考虑将它们作为正则表达式传递。根据您拥有的零长度条目的数量,这可能会明显更快。

请注意,如果您的默认字符集很奇怪,其中 0x00-0xFF 不映射到与 ASCII 相同的值(在任何地方都存在这样的字符集吗?),这将返回误报。否则,尽情享受吧!

于 2016-01-05T00:37:05.523 回答
2

尝试使用此查询搜索特殊字符记录

SELECT *
FROM tableName
WHERE fieldName REGEXP '[^a-zA-Z0-9@:. \'\-`,\&]'
于 2016-09-12T07:51:22.610 回答
0

@zende 的答案是唯一一个涵盖混合了 ascii 和非 ascii 字符的列,但它也有问题的十六进制内容。我用这个:

SELECT * FROM `table` WHERE NOT `column` REGEXP '^[ -~]+$' AND `column` !=''
于 2017-11-29T20:39:43.380 回答
0

在 Oracle 中,我们可以在下面使用。

SELECT * FROM TABLE_A WHERE ASCIISTR(COLUMN_A) <> COLUMN_A;
于 2019-02-28T06:37:53.470 回答
-2

对于这个问题,我们也可以使用这种方法:

来自 sql zoo 的问题:
查找 PETER GRÜNBERG 获奖的所有详细信息

非 ASCII 字符

ans: select*from nobel where Winner like 'P% GR%_%berg';

于 2018-03-25T14:38:13.933 回答