我有一张桌子:
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中是否有严格的比较修饰符?
答案 0 :(得分:5)
一个选项是CAST
112
到CHAR
以获得正确的匹配:
WHERE CAST(id AS CHAR(12)) = '112abcdefg'
12
中的CHAR
是一个猜测;对于你最大的id
,它应该足够大。
这可能会杀死任何优化的机会,所以另一种选择(尽管我不是100%肯定的)是使用BINARY
比较。我用几个不同的值尝试了这个并且它有效:
WHERE BINARY id = '112abcdefg'
答案 1 :(得分:4)
你正在比较一个字符串,只是把数字放在没有引号的地方:
SELECT * FROM `ids` WHERE id = 112
如果你不这样做,它会将字符串'112abcdefg'转换为数字并说出它的112
您看到的响应是因为您尝试将整数列与字符串值进行比较。在这种情况下,MySQL会将字符串文字值类型转换为整数,当它执行该操作时,它从字符串的左边开始,一旦到达不能被视为数字一部分的字符,它就会消失从那一点开始的一切。因此,尝试将“256abcd”与整数列进行比较将导致实际比较数字256。
所以你的选择(或至少其中一些)将是: 验证应用程序代码中的输入字符串,如果它不是整数,则拒绝它(请参阅PHP中的ctype_digit函数)。 如果要将其视为字符串(例如VARCHAR类型),请更改文件名的列类型。 将列值转换为字符串:
. . . WHERE CAST(Id AS CHAR) = '256aei'
答案 2 :(得分:1)
你可以用这个:
SET sql_mode = STRICT_TRANS_TABLES;
这会将sql模式设置为严格检查,然后尝试触发您提到的查询。
答案 3 :(得分:1)
跛脚+杀死优化但服务于它的目的
SELECT * FROM `ids` WHERE concat(id) = '112abcdefg';
通过这种方式强制转换为字符串 http://dev.mysql.com/doc/refman/5.1/en/type-conversion.html