2012-04-04 15 views
15
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を使用しています)は、私が質問を変更すると、仕事は、準備文付きのMySQLのLIMITキーワード

LIMIT 0, 10 

それは動作します。

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

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

コード:

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

どのようにパラメータをバインドしますか? – alexn

+0

'LIMIT'句に代入している値を'(int) 'にキャストし、それらを文字通りクエリに指定することで回避できます。これは、何かを壊すような方法で回避することはできませんsanitisationのステップです、有効な整数表現ではない文字列は '0'になります。最悪のシナリオでは、結果は得られません。 – DaveRandom

+0

$ comments = $ db-> prepare($ query);/*ここで$ dbはPDOオブジェクトです。*/$ comments-> execute(array($ post、$ min、$ max)); – genesisxyz

答えて

34

ここで問題です:

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

PDOStatement::execute()のマニュアルページは(強調鉱山)言う:

Parameters

input_parameters 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.

したがって、あなたのパラメータは、文字列として挿入なっています、最終的な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 

言っている何docs

The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments, which must both be nonnegative integer constants, with these exceptions:

  • Within prepared statements, LIMIT parameters can be specified using ? placeholder markers.

  • Within stored programs, LIMIT parameters can be specified using integer-valued routine parameters or local variables.

あなたの選択肢が含まれます:

  • バインドパラメータS一つずつので、あなたがタイプを設定することができますエミュレート

    $query = sprintf('SELECT id, content, date 
        FROM comment 
        WHERE post = ? 
        ORDER BY date DESC 
        LIMIT %d, %d', $min, $max); 
    
  • を無効(MySQLドライバが作るだろうバグ/機能を持って準備:パラメータとしてこれらの値を渡さないでください

    $comments->bindParam(1, $post, PDO::PARAM_STR); 
    $comments->bindParam(2, $min, PDO::PARAM_INT); 
    $comments->bindParam(3, $min, PDO::PARAM_INT); 
    
  • をそれは)数値引数を引用:

    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE); 
    
+0

これは確かに原因ですが、コードが助けにならないのを見る:) –

+3

ええ、コードは過大評価されていますxD –

+0

申し訳ありませんが、コードを投稿していませんが、 :) – genesisxyz

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

はこの問題を解決します。

+0

これは機能します!私はこれが正確に何かを見なければなりませんが、今のところ完璧です – genesisxyz

+8

他の答えはそれがどのように動作するかを示しています。単にエミュレートするPDOはデフォルトで準備を行い、タイプを設定せずに変数を静かにバインドするので、PDOはデフォルトで文字列として扱います。 SQLの文字列は引用符で囲んでエスケープする必要があります。したがって、LIMIT節に引用符があり、構文エラーがあります。ネイティブの準備文が使用されているときに、データベースはそれらをソートすることができます。 –