I have this weird problem. Why do these two implementations return different results?
$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
When I bind the amount it gives me different result. I'd rather not concatenate the string because of the SQL injections.
When you are using the array to pass the data, the data is passed as a string:
From the docs:
An array of values with as many elements as there are bound parameters in the SQL statement being executed. All values are treated as PDO::PARAM_STR.
However, when you are manually entering in the 1 into the query directly it is being treated as an int. Let me see if I can do some further digging to see what happens internally when a string is converted into an int for you.
Edit: This is probably one of the most similar bugs that have been submitted and accepted:
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)
So it looks like internally mysql is converting to a double when you pass it an int. That would explain rather nicely the behavior that you are seeing.
Here is a list of other similar (numbers not quite right) bugs you might be interested in:
http://bugs.mysql.com/bug.php?id=46037
http://bugs.mysql.com/bug.php?id=35071
http://bugs.mysql.com/bug.php?id=35071 <-- Good one showing difference between Win and Lin
And a filtered list of data type bugs that I perused which make for interesting reading.
Edit 2: Aha!
Here is a bug that rather perfectly explains your issue:
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'
来源:https://stackoverflow.com/questions/12155465/pdo-difference-between-binding-params-and-concatenating-string