23
SELECT id, content, date
FROM comment
WHERE post = ?
ORDER BY date DESC
LIMIT ?, ?

PDO (私は Apache 2.2.21、PHP 5.3.6 まで、および MySQL 5.5.9 を含む MAMP 2.0.5 を使用しています) でクエリを変更すると、これは機能しません。

LIMIT 0, 10

できます。

MySQL のバグを見ると、これは以前のバージョンのバグでしたが、これがまだ修正されているかどうかわかりません。

それでも問題が解決しない場合、別の方法で行の範囲を選択する方法はありますか?

コード:

$comments = $db->prepare($query); 
/* where $db is the PDO object */ 
$comments->execute(array($post, $min, $max)); 
4

2 に答える 2

49

問題は次のとおりです。

$comments = $db->prepare($query); 
/* where $db is the PDO object */ 
$comments->execute(array($post, $min, $max));

PDOStatement::execute()のマニュアルページには次のように書かれています(私のものを強調してください):

パラメーター

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

したがって、パラメーターは文字列として挿入されるため、最終的な SQL コードは次のようになります。

LIMIT '0', '10'

これは、MySQL が数値にキャストせずに解析エラーをトリガーする特定のケースです。

mysql> SELECT 1 LIMIT 0, 10;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)

mysql> SELECT 1 LIMIT '0', '10';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''0', '10'' at line 1

ドキュメントの説明:

このLIMIT句を使用して、SELECTステートメントによって返される行数を制限できます。LIMIT次の例外を除いて、1 つまたは 2 つの数値引数を取ります。これらは両方とも非負の整数定数でなければなりません。

  • 準備済みステートメント内で、LIMIT? を使用してパラメーターを指定できます。プレースホルダー マーカー。

  • ストアド プログラム内では、LIMIT整数値のルーチン パラメータまたはローカル変数を使用してパラメータを指定できます。

選択肢は次のとおりです。

  • パラメータを 1 つずつバインドして、タイプを設定できるようにします。

    $comments->bindParam(1, $post, PDO::PARAM_STR);
    $comments->bindParam(2, $min, PDO::PARAM_INT);
    $comments->bindParam(3, $min, PDO::PARAM_INT);
    
  • これらの値をパラメーターとして渡さないでください。

    $query = sprintf('SELECT id, content, date
        FROM comment
        WHERE post = ?
        ORDER BY date DESC
        LIMIT %d, %d', $min, $max);
    
  • エミュレートされた準備を無効にします (MySQL ドライバーには、数値引数を引用するバグ/機能があります)。

    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
    
于 2012-04-04T15:22:47.017 に答える
5

問題を解決するために、特定の属性を宣言できます。

$dbh->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );

他の答えは、それがどのように機能するかを示しています。PDO はデフォルトで準備をエミュレートするだけであり、型を設定せずに変数をサイレントにバインドしているため、PDO はデフォルトで変数を文字列として扱います。SQL の文字列は引用符で囲み、エスケープする必要があります。したがって、LIMIT 句に引用符があり、構文エラーが発生します。一方、ネイティブのプリペアド ステートメントが使用されている場合、データベースは適切な型を整理することができます。

于 2012-04-04T15:23:14.770 に答える