将字符串与数值字段进行比较会返回意外的结果

5

给定以下表格:

CREATE TABLE IF NOT EXISTS `users` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

添加几行:

INSERT INTO `users` (`id`,`name`) VALUES (NULL , 'Bob'),(NULL , 'Larry'),(NULL , 'Steve');

为什么这个查询会返回结果:

SELECT * FROM `users` WHERE id = "2this-is-not a numeric value"

结果:

query returned 1 row(s) in 0.0003 sec
id  name
-----------------
2   Larry

在where子句中使用的字符串明显被转换为数字值——谁说要这样做?我找不到任何文件表明mysql或PHP会自动转换我的字符串文字。
只有当数字字符是字符串中的第一个字符时,才能正常工作,"this 2 is not numeric"将不会返回结果。 "12 2"将变成12,"1 2"(一个空格两个)变成1。
如有任何解释此行为的文章或文档,将不胜感激。

MySQL使用单引号(')而不是双引号(")来表示字符串吗?它可能只是查看数值,尝试隐式地将其转换为数字,然后截断非数字值。那么...为什么你在一个数字字段上使用引号强制进行隐式转换呢?毋庸置疑,我认为这是奇怪的行为。 - xQbert
要么。我总是在代码中使用单引号,所以我总是将双引号发送到SQL。 - Chris Baker
我想知道如果你在select语句中将字符串隐式转换为bigint,会得到什么结果。如果你得到了2...那么这就是隐式转换,而且这种行为真的很奇怪。 - xQbert
再说一遍...你为什么要使用任何引号呢? - xQbert
在实际代码中,查询是由一个函数组装的,该函数将所有列名都包含在反引号(`)中,并将所有值都包含在引号中。显然,这个函数不能继续使用——自动转换很令人沮丧。 - Chris Baker
1个回答

9

1
SELECT CONVERT( "2this-is-not a numeric value", UNSIGNED ) 返回 2。也许你可以把这个加入到你的答案中。 - Mike
我希望没有任何一行的ID是“2yourmom”。当我说“WHERE id = '2yourmom'”时,我指的是ID确切等于该值。无论在哪种语言中,自动转换都很糟糕。不管怎样...感谢提供链接:D - Chris Baker
1
+1 这个说得很到位。MySQL 中的隐式转换会在将非数字值转换为整数后删除它们,然后进行隐式转换。这让我感到非常恐惧,但文档中确实如此。 - xQbert
2
太好了,现在我需要一个类似于 PHP/JS 中的 === 运算符,呵呵。 - Chris Baker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接