我最近刚修复了一些代码中的错误,并希望有人可以向我解释错误发生的原因。
我有这样的查询:
SELECT * FROM my_table WHERE my_field=13
出乎意料的是,这是返回my_field
等于13
或13a
的行。修复很简单,我将查询更改为:
SELECT * FROM my_table WHERE my_field='13'
我的问题是,这应该是这样的吗?我一直认为要返回类似的字段,你会使用类似的东西:
SELECT * FROM my_table WHERE my_field LIKE '13%'
LIKE + Wild Card与没有引号的equals运算符有什么区别?
答案 0 :(得分:3)
此语句返回my_field = '13a'
的行:
SELECT * FROM my_table WHERE my_field=13
因为MySQL在比较期间执行从字符串到数字的类型转换,所以将'13a'
转换为13
。更多关于in this documentation page。
添加引号会将整数转换为字符串,因此MySQL仅执行字符串比较。显然,'13'
不能等于'13a'
。
LIKE
子句始终执行字符串比较(除非其中一个操作数为NULL
,在这种情况下结果为NULL
)。
答案 1 :(得分:1)
我的猜测是因为你没有将它括在引号中,并且列是char / varchar列,MySQL试图将varchar列隐式转换为int。
如果该表中的某一行包含无法转换为int的值,则可能会出错。此外,由于转换,您可能不会使用该列上的任何索引。
答案 2 :(得分:1)
这与类型和类型转换有关。对于my_field=13
,13是一个整数,而my_field
在您的情况下可能是某种形式的文本/字符串。在这种情况下,mysql会尝试将两者都转换为浮点数并进行比较。
所以mysql试图将e,g,“13a”转换成一个浮点数,它将是13,而13 = 13
在my_field = '13'
中,两个操作数都是文本,将使用=
在my_field like '13%'
中,两个操作数也是文本,并且将使用LIKE进行比较,其中特殊%表示通配符。
您可以阅读mysql使用here的类型转换。
答案 3 :(得分:1)
这是因为MySQL类型转换以这种方式工作。见这里:http://dev.mysql.com/doc/refman/5.0/en/type-conversion.html
它也会发布警告。见下面的代码
mysql> select 12 = '12bibo';
+---------------+
| 12 = '12bibo' |
+---------------+
| 1 |
+---------------+
1 row in set, 1 warning (0.00 sec)
mysql> show warnings;
+---------+------+--------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '12bibo' |
+---------+------+--------------------------------------------+
1 row in set (0.00 sec)
看起来有人也提出了一个错误:http://bugs.mysql.com/bug.php?id=42241