8

我在 MySQL 中创建了这样的表:

DROP TABLE IF EXISTS `barcode`;
CREATE TABLE `barcode` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `code` varchar(40) COLLATE utf8_bin DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;


INSERT INTO `barcode` VALUES ('1', 'abc');

INSERT INTO `barcode` VALUES ('2', 'abc ');

然后我从表格条码中查询数据:

SELECT * FROM barcode WHERE `code` = 'abc ';

结果是:

+-----+-------+
|  id | code  |
+-----+-------+
|  1  |  abc  |
+-----+-------+
|  2  |  abc  |
+-----+-------+

但我希望结果集只有 1 条记录。我解决方法:

SELECT * FROM barcode WHERE `code` = binary 'abc ';

结果是 1 条记录。但我使用 NHibernate 和 MySQL 从映射表生成查询。那么如何解决这个案子呢?

4

6 回答 6

9

没有其他解决方法。要么将单个比较指定为存在,binary要么将整个数据库连接设置为binary. (做SET NAMES binary,可能有其他副作用!)

基本上,这种“惰性”比较是MySQL 的一个硬编码特性。要禁用它(按需!),您可以使用binary您显然已经做过的比较。这不是“解决方法”,而是真正的解决方法。

来自MySQL 手册

所有 MySQL 排序规则都是 PADSPACE 类型。这意味着比较 MySQL 中的所有 CHAR 和 VARCHAR 值,而不考虑任何尾随空格

当然,从用户的角度来看,还有很多其他的可能性可以达到相同的结果,即:

  • WHERE field = 'abc ' AND CHAR_LENGTH(field) = CHAR_LENGTH('abc ')
  • WHERE field REGEXP 'abc[[:space:]]'

这些问题是它们有效地禁用了快速索引查找,因此您的查询总是导致全表扫描。拥有巨大的数据集,这会产生很大的不同。

再次: PADSPACE是 MySQLs [VAR]CHAR 比较的默认值。您可以(并且应该)使用BINARY. 这是这样做的目的。

于 2012-04-27T07:55:33.520 回答
2

您可以尝试使用正则表达式匹配

SELECT * FROM barcode WHERE `code` REGEXP 'abc[[:space:]]'
于 2012-04-27T07:53:10.783 回答
1

我只是在处理带有通配符 (%) 的 LIKE 时的情况,导致意外结果。在搜索时,我还发现STRCMP(text1, text2)了比较两个字符串的 mysql 的字符串比较功能。但是使用带有 LIKE 的 BINARY 为我解决了这个问题。

SELECT * FROM barcode WHERE `code` LIKE BINARY 'abc ';
于 2014-06-17T07:04:48.980 回答
0

我假设你只想要一个结果,你可以使用LIMIT

SELECT * FROM barcode WHERE `code` = 'abc ' LIMIT 1;

要进行精确的字符串匹配,您可以使用Collation

 SELECT *
 FROM barcode
 WHERE code COLLATE utf8_bin = 'abc';
于 2012-04-27T07:47:55.917 回答
0

你可以这样做:

SELECT * FROM barcode WHERE `code` = 'abc ' 
AND CHAR_LENGTH(`code`)=CHAR_LENGTH('abc ');
于 2012-04-27T07:55:04.217 回答
-1

Kaii引用的那句话之后的句子基本上是“使用LIKE”:

在此上下文中的“比较”不包括 LIKE 模式匹配运算符,其尾随空格很重要

下面的例子表明这'Monty' = 'Monty '是真的,但不是'Monty' LIKE 'Monty '

但是,如果您使用LIKE,请注意包含'%','_''\'字符的文字字符串 :'%'并且'_'是通配符,'\'用于转义序列。

于 2013-04-22T14:29:00.837 回答