mysql, prepared statements, and automatic type conversion

夙愿已清 提交于 2019-12-24 00:47:20

问题


I am getting different results performing the exact same query using regular statements and prepared statements, and I think it's a type conversion bug.

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)

the real value of vlan is 184

it looks like the way mysql is handling type conversions is different for prepared statements and regular statements? does that make sense? how do i fix this?


回答1:


The expected data type of prepared statement parameters is determined upon statement preparation, and type conversion to that data type takes place prior to statement execution.

In your example, an integer parameter is expected; therefore the provided string is cast to an integer (184) before the statement is executed, and the comparison between the integer column vlan and the parameter is successful for the matching record.

The "regular" statement, by contrast, compares the integer column with a string; therefore the arguments are compared as floating point numbers, and no record has a matching vlan.

To avoid this situation, ensure that the data type cannot be determined upon preparation (or that the determined data type does not lose any information) - for example:

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


来源:https://stackoverflow.com/questions/5189224/mysql-prepared-statements-and-automatic-type-conversion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!