2009-03-23 51 views
38

estoy diseccionando un cierto código y me encontré con esto,¿Cuál es el significado del signo de interrogación en MySQL en "WHERE column =?"?

$sql = 'SELECT page.*, author.name AS author, updator.name AS updator ' 
    . 'FROM '.TABLE_PREFIX.'page AS page ' 
    . 'LEFT JOIN '.TABLE_PREFIX.'user AS author ON author.id = page.created_by_id ' 
    . 'LEFT JOIN '.TABLE_PREFIX.'user AS updator ON updator.id = page.updated_by_id ' 
    . 'WHERE slug = ? AND parent_id = ? AND (status_id='.Page::STATUS_REVIEWED.' OR status_id='.Page::STATUS_PUBLISHED.' OR status_id='.Page::STATUS_HIDDEN.')'; 

Me pregunto lo que el "?" lo hace en la declaración WHERE. ¿Es algún tipo de titular del parámetro?

Respuesta

35

Las declaraciones preparadas usan el '?' en MySQL para permitir params vinculantes a la declaración. Altamente considerado como más seguro contra las inyecciones de SQL si se usa correctamente. Esto también permite consultas SQL más rápidas, ya que la solicitud solo debe compilarse una vez y puede reutilizarse.

+0

¿Cómo los usaría uno? Con eso me refiero a cómo se establece el signo de interrogación para tomar un parámetro? – Levi

+1

Existen múltiples formas de hacer declaraciones preparadas, PDO y MySQLi las admiten. http://us3.php.net/mysqli http://us3.php.net/manual/en/mysqli.prepare.php y una búsqueda rápida en Google me llevaron a http://www.petefreitag.com/item/ 356.cfm – Jayrox

24

El signo de interrogación representa un parámetro que luego será reemplazado. Usar consultas parametrizadas es más seguro que insertar los parámetros directamente en la consulta.

SQL Server llama a esta parametrización de consultas, y Oracle se unen llama variables.

El uso varía con el idioma que se está ejecutando la consulta de.

Aquí hay un ejemplo de cómo se usa desde PHP.

suponiendo que $mysqli es una conexión de base de datos y people es una tabla con 4 columnas.

$stmt = $mysqli->prepare("INSERT INTO People VALUES (?, ?, ?, ?)"); 

$stmt->bind_param('sssd', $firstName, $lastName, $email, $age); 

El 'sssd' es una bandera que identifica el resto de los parámetros, donde s representa cuerda y d representa dígitos.

1

Estas son declaraciones preparadas, las declaraciones preparadas ofrecen dos ventajas principales:

La consulta sólo necesita ser analizado (o preparados) una vez, pero puede ser ejecuta varias veces con el mismo o diferentes parámetros. Cuando se prepara la consulta, la base de datos analizará, compilará y optimizará su plan para ejecutar la consulta. Para consultas complejas este proceso puede tardar hasta suficiente tiempo que va a ralentizar notablemente una aplicación si hay una necesidad de repetir la misma consulta muchas veces con diferentes parámetros . Al usar una declaración preparada, la aplicación evita repitiendo el ciclo analizar/compilar/optimizar. Esto significa que las declaraciones preparadas usan menos recursos y, por lo tanto, se ejecutan más rápido.

Los parámetros para las declaraciones preparadas no necesitan ser citados; el controlador maneja esto automáticamente. Si una aplicación utiliza exclusivamente declaraciones preparadas, el desarrollador puede estar seguro de que ninguna inyección SQL se producirá (sin embargo, si otras partes de la consulta se construyen las con la entrada sin escape, inyección SQL es aún posible).

http://php.net/manual/en/pdo.prepared-statements.php

5

Ninguno

? no significa nada para MySQL WHERE = cláusula, sólo varias interfaces externas tales como PHP y stdlib web frameworks como rieles.

? es simplemente un error de sintaxis en:

CREATE TABLE t (s CHAR(1)); 
SELECT * FROM t WHERE s = ?; 

porque es sin comillas, como en:

INSERT INTO t VALUES ('a'); 
INSERT INTO t VALUES ("?"); 
SELECT * FROM t WHERE s = '?'; 

que devuelve:

s 
? 

tanto, aparentemente sin significado especial.

rieles ejemplo

En Rails por ejemplo, el signo de interrogación se sustituye por un argumento dado por una variable del lenguaje de programación de la biblioteca (Rubí), por ejemplo:

Table.where("column = ?", "value") 

y automáticamente argumentos de cotizaciones para evitar errores e inyección de SQL, generando una declaración como:

SELECT * FROM Table WHERE column = 'value'; 

La cotización wo ULD nos salva en caso de algo así como:

Table.where("column = ?", "; INJECTION") 

MySQL 5.0 declaraciones preparadas

MySQL 5.0 añade el prepared statement feature que tiene una semántica similar al signo de interrogación en los marcos web.

Ejemplo a partir de los documentos:

PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; 
SET @a = 3; 
SET @b = 4; 
EXECUTE stmt1 USING @a, @b; 

de salida:

hypotenuse 
5 

Estos también escapar caracteres especiales como se esperaba:

PREPARE stmt1 FROM 'SELECT ? AS s'; 
SET @a = "'"; 
EXECUTE stmt1 USING @a; 

de salida:

s 
' 
Cuestiones relacionadas