LIMIT keyword on MySQL with prepared statement

limit, mysql, php, prepared-statement

Solution

Here's the problem:

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

The manual page for PDOStatement::execute() says (emphasis mine):

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.

Thus your parameters are getting inserted as strings, so the final SQL code looks like this:

LIMIT '0', '10'

This is a particular case where MySQL will not cast to number but trigger a parse error:

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

What docs have to say:

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.

Your choices include:

Bind parameters one by one so you can set a type:

$comments->bindParam(1, $post, PDO::PARAM_STR);
$comments->bindParam(2, $min, PDO::PARAM_INT);
$comments->bindParam(3, $min, PDO::PARAM_INT);

Do not pass those values as parameters:

$query = sprintf('SELECT id, content, date
    FROM comment
    WHERE post = ?
    ORDER BY date DESC
    LIMIT %d, %d', $min, $max);

Disable emulated prepares (the MySQL driver has a bug/feature that will make it quote numeric arguments):

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

Problem

``` SELECT id, content, date FROM comment WHERE post = ? ORDER BY date DESC LIMIT ?, ? ``` With PDO (I'm using MAMP 2.0.5 that has Apache 2.2.21, PHP up to 5.3.6, and MySQL 5.5.9) prepared statement this doesn't work, if I change the query with ``` LIMIT 0, 10 ``` it works. I see in the bugs of MySQL that this was a bug in previous version but I can't understand if this is still to be fixed. If this is still a problem, there is a way to select a range of rows in another way? code: ``` $comments = $db->prepare($query); /* where $db is the PDO object */ $comments->execute(array($post, $min, $max)); ```

Original source

Related problems