2

私はこの奇妙な問題を抱えています。これら 2 つの実装が異なる結果を返すのはなぜですか?

    $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 インジェクションのため、文字列を連結したくありません。

4

1 に答える 1

4

配列を使用してデータを渡す場合、データは文字列として渡されます。

ドキュメントから:

実行中の SQL ステートメントにバインドされたパラメーターと同じ数の要素を持つ値の配列。すべての値は PDO::PARAM_STR として扱われます。

ただし、手動で1クエリに直接入力すると、int として扱われます。文字列が int に変換されたときに内部で何が起こるかをさらに掘り下げることができるかどうか見てみましょう。

編集: これはおそらく、提出され受け入れられた最も類似したバグの 1 つです。

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)

そのため、int を渡すと、内部的に mysql が 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 の違いを示す良い例

そして、私が熟読したデータ型のバグのフィルタリングされたリストは、興味深い読み物になります。

編集2:ああ!

これは、問題をかなり完全に説明するバグです。

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'
于 2012-08-28T08:35:19.820 に答える