2009-03-23 24 views
38

Sto dissezione po 'di codice e sono imbattuto in questo,Qual è il significato del punto interrogativo in MySQL su "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.')'; 

Mi chiedo quale sia il "?" fa nella dichiarazione WHERE. È una sorta di proprietario di parametri?

risposta

35

Gli statuti preparati utilizzano "?" in MySQL per consentire i param vincoli alla dichiarazione. Molto considerato come più sicuro contro le iniezioni SQL se usato correttamente. Ciò consente anche query SQL più veloci poiché la richiesta deve essere compilata una sola volta e può essere riutilizzata.

+0

Come si usano? Con ciò intendo come si imposta il punto interrogativo su un parametro? – Levi

+1

Esistono diversi modi per eseguire istruzioni preparate, PDO e MySQLi supportano. http://us3.php.net/mysqli http://us3.php.net/manual/en/mysqli.prepare.php e una rapida ricerca su google mi ha portato a http://www.petefreitag.com/item/ 356.cfm – Jayrox

24

Il punto interrogativo rappresenta un parametro che verrà in seguito sostituito. L'utilizzo di query parametrizzate è più sicuro rispetto all'integrazione dei parametri direttamente nella query.

SQL Server chiama questa query di parametri e Oracle chiama variabili di collegamento.

L'utilizzo varia con la lingua da cui si sta eseguendo la query.

Ecco un esempio di come viene utilizzato da PHP.

presupponendo che sia una connessione di database e people è una tabella con 4 colonne.

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

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

Il 'sssd' è un flag che identifica il resto dei parametri, dove s rappresenta stringa e d rappresenta cifre.

1

Queste sono istruzioni preparate, istruzioni preparate offrono due importanti vantaggi:

L'interrogazione deve solo essere analizzato (o preparati) una volta, ma può essere più volte eseguiti con gli stessi o diversi parametri. Quando viene preparata la query , il database analizzerà, compilerà e ottimizzerà il proprio piano per l'esecuzione della query. Per le query complesse, questo processo può richiedere tempo sufficiente per rallentare notevolmente un'applicazione se è necessario ripetere la stessa query molte volte con diversi parametri . Utilizzando una dichiarazione preparata l'applicazione evita ripetendo il ciclo di analisi/compilazione/ottimizzazione. Ciò significa che le istruzioni preparate utilizzano meno risorse e quindi funzionano più velocemente.

I parametri per le istruzioni preparate non devono essere citati; il driver gestisce automaticamente questo. Se un'applicazione utilizza esclusivamente istruzioni preparate , lo sviluppatore può essere certo che non si verificherà alcuna iniezione SQL (tuttavia, se altre parti della query vengono create con input senza caratteri di escape, l'iniezione SQL è ancora possibile).

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

5

Nessuno

? significa niente per MySQL WHERE = clausola, solo per diverse interfacce esterne come PHP stdlib e web framework come Rails.

? è solo un errore di sintassi a:

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

perché è non quotati, e in:

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

ritorna:

s 
? 

così apparentemente senza significato speciale.

Rails esempio

In Rails, ad esempio, il punto di domanda è sostituito da un argomento dato da una variabile del linguaggio di programmazione della biblioteca (Ruby), ad esempio:

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

ed automaticamente cita argomenti per evitare bug e SQL injection, generando una dichiarazione come:

SELECT * FROM Table WHERE column = 'value'; 

Il citando wo ULD salvaci in caso di qualcosa come:

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

MySQL 5.0 istruzioni preparate

MySQL 5.0 aggiunto il prepared statement feature che ha una semantica simili al punto di domanda nel framework web.

Esempio dalla documentazione:

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

uscita:

hypotenuse 
5 

Questi inoltre sfuggire caratteri speciali come previsto:

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

uscita:

s 
' 
Problemi correlati