SQL等值查询同时匹配id=3与指定uid的异常原因是什么
问题原因
你遇到的现象不是等值查询变成了模糊查询,是MySQL隐式类型转换导致的匹配异常。
首先你的表结构满足两个前提:
id字段为数值类型(如INT、BIGINT)uid字段为字符串类型(如VARCHAR)
当你执行如下查询时:
SELECT u0_.id AS id_0, u0_.uid AS uid_1, u0_.username AS username_2 FROM user u0_ WHERE u0_.uid = '3XW3Z1zD6JEV1600164577' OR u0_.id = '3XW3Z1zD6JEV1600164577';
u0_.id = '3XW3Z1zD6JEV1600164577' 这部分运算两侧分别是数值类型和字符串类型,MySQL会自动把字符串转换为数值再做比较。
字符串转数值的规则是:从左到右逐字符解析,遇到第一个非数字字符就停止解析,只保留前面的数字部分:
- 字符串
'3XW3Z1zD6JEV1600164577'开头是数字3,下一个字符是字母X,转换后数值就是3 - 去掉开头
3后的字符串'XW3Z1zD6JEV1600164577'第一个字符就是非数字,转换后数值为0
所以实际执行的WHERE条件等价于:
WHERE u0_.uid = '3XW3Z1zD6JEV1600164577' OR u0_.id = 3
自然会同时返回uid匹配的用户和id=3的用户。
修复方案
- 显式统一比较两侧的类型,避免隐式转换:将id字段转成字符串后再做等值匹配
SELECT u0_.id AS id_0, u0_.uid AS uid_1, u0_.username AS username_2 FROM user u0_ WHERE u0_.uid = '3XW3Z1zD6JEV1600164577' OR CAST(u0_.id AS CHAR) = '3XW3Z1zD6JEV1600164577';
- 业务层区分id和uid的查询逻辑,不要用同一个字符串参数同时匹配数值类型的id和字符串类型的uid。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

