Mysql
 sql >> Base de données >  >> RDS >> Mysql

Mot clé LIMIT sur MySQL avec instruction préparée

Voici le problème :

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

La page de manuel pour PDOStatement::execute() dit (c'est moi qui souligne) :

Paramètres

input_parameters Un tableau de valeurs avec autant d'éléments qu'il y a de paramètres liés dans l'instruction SQL en cours d'exécution. Toutes les valeurs sont traitées comme PDO ::PARAM_STR .

Ainsi, vos paramètres sont insérés sous forme de chaînes, de sorte que le code SQL final ressemble à ceci :

LIMIT '0', '10'

Il s'agit d'un cas particulier où MySQL ne convertira pas en nombre mais déclenchera une erreur d'analyse :

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

Quelle documents je dois dire :

La LIMIT La clause peut être utilisée pour limiter le nombre de lignes renvoyées par le SELECT déclaration. LIMIT prend un ou deux arguments numériques, qui doivent tous deux être des constantes entières non négatives, avec ces exceptions :

  • Dans les instructions préparées, LIMIT les paramètres peuvent être spécifiés en utilisant ? marqueurs d'espace réservé.

  • Dans les programmes stockés, LIMIT les paramètres peuvent être spécifiés à l'aide de paramètres de routine à valeur entière ou de variables locales.

Vos choix incluent :

  • Liez les paramètres un par un pour pouvoir définir un type :

    $comments->bindParam(1, $post, PDO::PARAM_STR);
    $comments->bindParam(2, $min, PDO::PARAM_INT);
    $comments->bindParam(3, $min, PDO::PARAM_INT);
    
  • Ne transmettez pas ces valeurs en tant que paramètres :

    $query = sprintf('SELECT id, content, date
        FROM comment
        WHERE post = ?
        ORDER BY date DESC
        LIMIT %d, %d', $min, $max);
    
  • Désactivez les préparations émulées (le pilote MySQL a un bogue/fonctionnalité qui lui fera citer des arguments numériques) :

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