【问题标题】:mysql, prepared statements, and automatic type conversionmysql、prepared statements 和自动类型转换
【发布时间】:2011-07-08 12:50:50
【问题描述】:

使用常规语句和准备好的语句执行完全相同的查询时,我得到了不同的结果,我认为这是一个类型转换错误。

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 处理类型转换的方式对于准备好的语句和常规语句是不同的?那有意义吗?我该如何解决这个问题?

【问题讨论】:

  • 如果执行where vlan = '184.182'会怎样?
  • 如前所述,在这种情况下没有任何结果

标签: mysql types type-conversion prepared-statement


【解决方案1】:

预编译语句参数的预期数据类型在语句准备时确定,并且在语句执行之前进行到该数据类型的类型转换。

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

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

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

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

【讨论】:

    猜你喜欢
    • 2014-03-29
    • 2013-08-25
    • 2015-09-03
    • 1970-01-01
    • 2013-05-05
    • 2012-08-23
    • 1970-01-01
    • 2012-10-04
    • 1970-01-01
    相关资源
    最近更新 更多