mysql,预处理语句和自动类型转换

时间:2011-03-04 03:12:26

标签: mysql types type-conversion prepared-statement

我使用常规语句和预处理语句执行完全相同的查询得到不同的结果,我认为这是一种类型转换错误。

mysql> show columns from server where field = "vlan";
+-------------+--------+------+-----+---------+-------+
| Field       | Type   | Null | Key | Default | Extra |
+-------------+--------+------+-----+---------+-------+
| vlan        | int(5) | YES  | MUL | NULL    |       |
+-------------+--------+------+-----+---------+-------+

mysql> select hostname from server where `vlan` = '184.182' limit 1;
Empty set (0.00 sec)

mysql> prepare stupid from "select hostname from server where `vlan` = ? limit 1";
Query OK, 0 rows affected (0.00 sec)
Statement prepared

mysql> set @vlan = '184.182';
Query OK, 0 rows affected (0.00 sec)

mysql> execute stupid using @vlan;
+-------------------+
| hostname          |
+-------------------+
| web20.servers.com |
+-------------------+
1 row in set (0.00 sec)

vlan的实际值为184

看起来mysql处理类型转换的方式对于预处理语句和常规语句是不同的?那有意义吗?我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

预处理语句参数的预期数据类型是在语句准备时确定的,并且在语句执行之前将类型转换为该数据类型。

在您的示例中,需要一个整数参数;因此,在执行语句之前,将提供的字符串强制转换为整数(184),并且匹配记录的整数列vlan与参数之间的比较成功。

相反,“regular”语句将整数列与字符串进行比较;因此,参数被比较为浮点数,并且没有记录具有匹配的vlan

要避免这种情况,请确保在准备时无法确定数据类型(或确定的数据类型不会丢失任何信息) - 例如:

prepare not_so_stupid from
  "select hostname from server where `vlan` = CAST(? AS CHAR) limit 1"
;