8

我有一张桌子:

CREATE TABLE `ids` (
    id int(11) not null auto_increment,
    PRIMARY KEY (id)
);

它包含一些 ID:111、112、113、114 等。

我做了一个查询:

SELECT * FROM `ids` WHERE id = '112abcdefg'

我没有预料到,但我得到了一个结果,一行 ID 为 112。似乎 MySQL 悄悄地将我的字符串转换为整数,然后将它与列值进行比较。

如何更改查询,以便从id列中查询相同的字符串不会给出我期望的结果?MySQL中是否有严格的比较修饰符?

4

4 回答 4

5

一种选择是 toCAST获得112适当CHAR的匹配:

WHERE CAST(id AS CHAR(12)) = '112abcdefg'

里面是一个猜测12CHAR它应该足以容纳您最大的id.

这可能会扼杀任何优化的机会,所以另一种选择(虽然我不是 100% 肯定)是使用BINARY比较。我已经用几个不同的值尝试了这个并且它有效:

WHERE BINARY id = '112abcdefg'
于 2013-05-29T18:14:00.397 回答
4

您正在比较一个字符串,只需输入不带引号的数字:

SELECT * FROM `ids` WHERE id = 112

如果你不这样做,它会将字符串 '112abcdefg' 转换为一个数字并说它的 112

您看到的响应是因为您正在尝试将整数列与字符串值进行比较。在这种情况下,MySQL 会将字符串文字值类型转换为整数,并且当它这样做时,它会从字符串的左侧开始,一旦到达不能被视为数字一部分的字符,它就会删除从那时起的一切。因此,尝试将“256abcd”与整数列进行比较将导致实际比较数字 256。

因此,您的选择(或至少其中一些)将是:验证应用程序代码中的输入字符串,如果它不是整数则拒绝它(请参阅 PHP 中的 ctype_digit 函数)。如果要将文件名视为字符串(例如 VARCHAR 类型),请更改文件名的列类型。将列值转换为字符串:

. . . WHERE CAST(Id AS CHAR) = '256aei'

资源

于 2013-05-29T18:11:44.470 回答
1

你可以使用这个:

SET sql_mode = STRICT_TRANS_TABLES;

这会将您的 sql 模式设置为严格检查,然后尝试触发您提到的查询。

于 2013-05-29T18:13:14.363 回答
1

蹩脚+杀死优化,但服务于它的目的

SELECT * FROM `ids` WHERE concat(id) = '112abcdefg';

这样你就可以强制转换为字符串 http://dev.mysql.com/doc/refman/5.1/en/type-conversion.html

于 2013-05-29T18:24:27.510 回答