mysql、准备好的语句和自动类型转换

发布于 2024-10-20 03:15:06 字数 1009 浏览 1 评论 0原文

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ぶ宁プ宁ぶ 2024-10-27 03:15:06

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

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

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

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

prepare not_so_stupid from
  "select hostname from server where `vlan` = CAST(? AS CHAR) limit 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"
;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文