Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Palavra-chave LIMIT no MySQL com instrução preparada


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

A página de manual para PDOStatement::execute() diz (grifo meu):

Parâmetros

input_parameters Uma matriz de valores com tantos elementos quantos são os parâmetros vinculados na instrução SQL que está sendo executada. Todos os valores são tratados como PDO::PARAM_STR .

Assim, seus parâmetros estão sendo inseridos como strings, então o código SQL final fica assim:
LIMIT '0', '10'

Este é um caso particular em que o MySQL não converterá para número, mas acionará um erro de análise:
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

O que documentos tem que dizer:

O LIMIT cláusula pode ser usada para restringir o número de linhas retornadas pelo SELECT demonstração. LIMIT recebe um ou dois argumentos numéricos, que devem ser constantes inteiras não negativas, com estas exceções:

  • Dentro de instruções preparadas, LIMIT parâmetros podem ser especificados usando ? marcadores de lugar.

  • Dentro dos programas armazenados, LIMIT parâmetros podem ser especificados usando parâmetros de rotina de valor inteiro ou variáveis ​​locais.

Suas escolhas incluem:

  • Ligue os parâmetros um por um para que você possa definir um tipo:
    $comments->bindParam(1, $post, PDO::PARAM_STR);
    $comments->bindParam(2, $min, PDO::PARAM_INT);
    $comments->bindParam(3, $min, PDO::PARAM_INT);
    

  • Não passe esses valores como parâmetros:
    $query = sprintf('SELECT id, content, date
        FROM comment
        WHERE post = ?
        ORDER BY date DESC
        LIMIT %d, %d', $min, $max);
    

  • Desabilite preparações emuladas (o driver MySQL tem um bug/recurso que o fará citar argumentos numéricos):
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);