php pdo prepared-statement

php - ¿Cómo uso la declaración preparada de pdo para las cláusulas de orden y límite?



prepared-statement (4)

Quiero usar una declaración preparada en la que los parámetros pasados ​​sean para las cláusulas ORDER BY y LIMIT , de este modo:

$sql = ''SELECT * FROM table ORDER BY :sort :dir LIMIT :start, :results''; $stmt = $dbh->prepare($sql); $stmt->execute(array( ''sort'' => $_GET[''sort''], ''dir'' => $_GET[''dir''], ''start'' => $_GET[''start''], ''results'' => $_GET[''results''], ) );

Pero $stmt->fetchAll(PDO::FETCH_ASSOC); no devuelve nada.

¿Alguien puede señalar qué es lo que estoy haciendo mal? Se puede hacer? Si no es así, ¿a qué debo referirme para obtener una lista completa de las cláusulas donde se pueden usar los parámetros?


Aunque esta pregunta es bastante antigua, creo que todavía podría ser de interés. Para mi funciono despues de

  1. usó bindParam en combinación con PDO::PARAM_INT como se sugirió antes
  2. convirtió el contenido de la variable en un valor entero invocando intval()

La parte relevante del código se ve así:

$stmt->bindParam('':start'', intval($_GET[''start'']), PDO::PARAM_INT); $stmt->bindParam('':number'', intval($_GET[''number'']), PDO::PARAM_INT);

Sin usar intval() también recibí el error Error de sintaxis o infracción de acceso: 1064 Tienes un error en tu sintaxis de SQL; consulte el manual que corresponde a la versión de su servidor MySQL para conocer la sintaxis correcta para usar cerca de '''' 0 '', 10'' en la línea 1


Después de usar:

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Recibí el mensaje :

Excepción no detectada ''PDOException'' con mensaje ''SQLSTATE [42000]: Error de sintaxis o infracción de acceso: 1064 Tiene un error en su sintaxis SQL; consulte el manual que corresponde a la versión de su servidor MySQL para conocer la sintaxis correcta para usar cerca de '''' 0 '','' 10 '''' en la línea 1

Por lo tanto, cuando usa una matriz para ejecutar, considera sus entradas como una cadena que no es una buena idea para LIMIT

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sql = "SELECT * FROM table ORDER BY :sort :dir LIMIT :start, :results"; $stmt = $dbh->prepare($sql); $stmt->bindParam('':start'', $_GET[''start''], PDO::PARAM_INT); $stmt->bindParam('':results'', $_GET[''results''], PDO::PARAM_INT); $stmt->bindParam('':sort'', $_GET[''sort'']); $stmt->bindParam('':dir'', $_GET[''dir'']); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); print_r($data);


Las declaraciones preparadas permiten que el DBMS genere un plan de consulta para su consulta antes de ejecutar la consulta para sus parámetros proporcionados. Cambiar los campos para ORDER BY requiere un plan de consulta diferente, porque ordenar sus datos de diferentes maneras puede afectar drásticamente cómo el DBMS puede elegir obtener los datos: por ejemplo, ciertos índices pueden ayudar en un caso pero no en otro. Por esta razón, los campos ORDER BY deben formar parte de la cadena SQL que se pasa al método prepare() , en lugar de estar vinculados a la consulta antes de execute() .

En cuanto a la cláusula LIMIT , no está claro si sus parámetros afectarían el plan de consulta, por lo que estos pueden vincularse más adelante, posiblemente dependiendo de su DBMS. De acuerdo con esta respuesta, se debe permitir.


No puede enlazar un parámetro para especificar una palabra clave de idioma o un nombre de campo; tiene que estar reemplazando un literal. Por lo tanto, sus valores límite creo que están bien, pero su orden no lo está. Será mejor para usted reemplazar manualmente ordenar y dir en la cadena. Escápalos pero no utilices las herramientas de DB para hacerlo, ya que no son literales de cadena. Básicamente, asegúrese de que no haya caracteres especiales presentes.