Mysql
 sql >> Database >  >> RDS >> Mysql

Parola chiave LIMIT su MySQL con istruzione preparata

Ecco il problema:

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

La pagina del manuale per PDOStatement::execute() dice (sottolineatura mia):

Parametri

input_parameters Una matrice di valori con tanti elementi quanti sono i parametri associati nell'istruzione SQL in esecuzione. Tutti i valori vengono trattati come PDO::PARAM_STR .

Quindi i tuoi parametri vengono inseriti come stringhe, quindi il codice SQL finale è simile a questo:

LIMIT '0', '10'

Questo è un caso particolare in cui MySQL non eseguirà il cast al numero ma attiverà un errore di analisi:

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

Quali documenti devo dire:

Il LIMIT La clausola può essere utilizzata per vincolare il numero di righe restituite da SELECT dichiarazione. LIMIT accetta uno o due caratteri numerici, che devono essere entrambi costanti intere non negative, con queste eccezioni:

  • All'interno delle istruzioni preparate, LIMIT i parametri possono essere specificati usando ? segnaposto.

  • All'interno dei programmi memorizzati, LIMIT i parametri possono essere specificati utilizzando parametri di routine a valori interi o variabili locali.

Le tue scelte includono:

  • Associa i parametri uno per uno in modo da poter impostare un tipo:

    $comments->bindParam(1, $post, PDO::PARAM_STR);
    $comments->bindParam(2, $min, PDO::PARAM_INT);
    $comments->bindParam(3, $min, PDO::PARAM_INT);
    
  • Non passare quei valori come parametri:

    $query = sprintf('SELECT id, content, date
        FROM comment
        WHERE post = ?
        ORDER BY date DESC
        LIMIT %d, %d', $min, $max);
    
  • Disabilita l'emulazione prepara (il driver MySQL ha un bug/una funzionalità che gli farà citare argomenti numerici):

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