我当时正在做一些系统测试,希望mysql(5.7.21)的结果是空的,但得到的结果让我很惊讶。
我的事务表如下所示:
Column Data type
----------------------------
id | INT
fullnames | VARCHAR(40)
---------------------------
我有一些记录
--------------------------------
id | fullnames
--------------------------------
20 | Mutinda Boniface
21 | Boniface M
22 | Some-other Guy
-------------------------------
我的示例查询:
select * from transactions where id = "20"; -- gives me 1 record which is fine
select * from transactions where id = 20; -- gives me 1 record - FINE as well
现在,当我尝试这些时,它变得有趣了:
select * from transactions where id = "20xxx"; -- gives me 1 record - what is happening here?
mysql在这里做什么??
1条答案
按热度按时间falq053o1#
mysql在类型转换方面又快又松。当隐式地将字符转换为数字时,只要字符是数字,它就会从字符串的开头开始,而忽略其余的字符。在你的例子中, `` 不是数字,所以mysql只取开头的“20”。
解决这个问题的一种方法(这对性能很糟糕,因为您可能会丢失对列的索引的用法)是显式地将数字端强制转换为字符:
编辑:
从注解中引用关于性能的讨论—在客户端对一个数字执行强制转换可能是最好的方法,因为这样可以避免在您知道不应返回任何行时(即,当您的输入不是有效的数字时,例如“20x”)向数据库发送查询。
另一种方法是将输入转换成一个数字,再转换回一个字符串,然后比较长度。如果长度相同,则表示输入字符串已完全转换为数字,且未省略任何字符。这应该是ok wrt性能,因为此比较是在输入的字符串上执行的,而不是在列中的值上执行的,并且如果条件通过输入的短路评估,则仍然可以使用列的索引: