我有这个奇怪的问题。为什么这两个实现会返回不同的结果?
$db = DbBase::getInstance();
$stmt = $db->prepare('SELECT round(round(9.50 * :amount, 2) * 23 * 0.01, 2)');
$stmt->execute(array(':amount' => 1));
echo $stmt->fetchColumn();
Result: 2.18
$db = DbBase::getInstance();
$stmt = $db->prepare('SELECT round(round(9.50 * 1, 2) * 23 * 0.01, 2)');
$stmt->execute();
echo $stmt->fetchColumn();
Result: 2.19
当我绑定金额时,它会给我不同的结果。由于SQL注入,我宁愿不连接字符串。
答案 0 :(得分:4)
当您使用数组传递数据时,数据将作为字符串传递:
来自docs:
具有与正在执行的SQL语句中的绑定参数一样多的元素的值数组。所有值都被视为PDO :: PARAM_STR。
但是,当您直接在1
中手动输入查询时,它将被视为int。让我看看是否可以进一步挖掘,看看当你将字符串转换为int时内部会发生什么。
编辑:这可能是已提交和接受的most similar bugs之一:
1)
SET @a = 1;
SELECT @a;
2)
SET @a = 1.1;
SELECT @a;
.. and this
3)
SET @a = 1.1;
SELECT @a + 7;
returns '8.100000000000000000000000000000'
(probably the addition will convert "1.1" to a double, the result
of the addition is also a DOUBLE and finally the DOUBLE is converted
to a string - that should be OK as well as far as I can understand)
所以看起来内部mysql在传递int时会转换为double。这可以很好地解释你所看到的行为。
以下是您可能感兴趣的其他类似(数字不太正确)错误的列表:
http://bugs.mysql.com/bug.php?id=46037
http://bugs.mysql.com/bug.php?id=35071
http://bugs.mysql.com/bug.php?id=35071< - 好的一个显示Win和Lin之间的差异
我阅读了filtered list of data type bugs,这有助于阅读。
编辑2:啊哈!
以下bug that rather perfectly解释了您的问题:
Reproduce code:
---------------
CREATE TABLE my_db.my_table (
id int(10) unsigned NOT NULL auto_increment,
PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
<?php
$DB = new PDO('mysql:dbname=my_db;host=localhost', 'user', 'pass');
$stmt = $DB->prepare('select * from my_table where id>?');
$stmt->bindValue(1, 13);
$stmt->execute();
?>
or
<?php
$DB = new PDO('mysql:dbname=my_db;host=localhost', 'user', 'pass');
$stmt = $DB->prepare('select * from my_table where id>?');
$stmt->execute(array(13));
?>
Expected result:
----------------
select * from my_table where id>13
Actual result:
--------------
select * from my_table where id>'13'