statement - transact sql select




Come gestisco le citazioni in SQL (6)

Questa domanda ha già una risposta qui:

Ho un database con nomi come John Doe, ecc. Sfortunatamente alcuni di questi nomi contengono citazioni come Keiran O'Keefe. Ora quando provo a cercare nomi come questi:

SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe' 

Io (comprensibilmente) ho un errore.

Come impedire che si verifichi questo errore. Sto usando Oracle e PLSQL.


Il filtraggio degli input viene generalmente eseguito a livello di lingua anziché a livello di database.
php e .NET hanno entrambe le rispettive librerie per l'escaping di istruzioni SQL. Controlla la tua lingua, vedi disponibile.
Se i tuoi dati sono affidabili, puoi semplicemente sostituire una stringa per aggiungere un altro "davanti a" per evitarlo. Di solito questo è sufficiente se non ci sono rischi che l'input sia dannoso.


Le query parametrizzate sono tuoi amici, come suggerito da Matt.

Command = SELECT * FROM PEOPLE WHERE SURNAME=?

Ti proteggeranno dai mal di testa coinvolti con

  • Archi con citazioni
  • Interrogazione utilizzando le date
  • SQL Injection


L'uso di SQL con parametri ha altri vantaggi, riduce il sovraccarico della CPU (così come altre risorse) in Oracle riducendo la quantità di lavoro richiesta da Oracle per analizzare la dichiarazione. Se non usi i parametri (li chiamiamo variabili bind in Oracle) quindi "seleziona * da foo dove bar = 'cat'" e "seleziona * da foo dove bar = 'dog'" sono trattati come istruzioni separate, dove come " seleziona * da foo dove bar =: b1 "è la stessa istruzione, cioè cose come la sintassi, la validità degli oggetti a cui si fa riferimento ecc ... non è necessario ricontrollare. Ci sono problemi occasionali che sorgono quando si usano variabili di bind che di solito si manifestano nel non ottenere il piano di esecuzione SQL più efficiente ma ci sono soluzioni per questo problema e questi problemi dipendono realmente dai predicati che si stanno utilizzando, indicizzazione e inclinazione dei dati.


Per trattare le virgolette se stai usando Zend Framework, ecco il codice

$db = Zend_Db_Table_Abstract::getDefaultAdapter();

$db->quoteInto('your_query_here = ?','your_value_here');

per esempio ;

//SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe' will become
SELECT * FROM PEOPLE WHERE SURNAME='\'O\'Keefe\''

Il carattere di escape è ', quindi è necessario sostituire la citazione con due virgolette.

Per esempio,

SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe'

diventa

SELECT * FROM PEOPLE WHERE SURNAME='O''Keefe'

Detto questo, probabilmente non è corretto farlo da soli. La tua lingua potrebbe avere una funzione per sfuggire alle stringhe da utilizzare in SQL, ma un'opzione ancora migliore è l'utilizzo dei parametri. Di solito questo funziona come segue.

Il tuo comando SQL sarebbe:

SELECT * FROM PEOPLE WHERE SURNAME=?

Quindi, quando lo si esegue, si passa in "O'Keefe" come parametro.

Poiché l'SQL viene analizzato prima che il valore del parametro sia impostato, non è possibile che il valore del parametro modifichi la struttura di SQL (ed è persino un po 'più veloce se si desidera eseguire la stessa istruzione più volte con parametri diversi).

Dovrei anche sottolineare che, mentre il tuo esempio causa solo un errore, ti apri a molti altri problemi non evitando le stringhe in modo appropriato. Vedi http://en.wikipedia.org/wiki/SQL_injection per un buon punto di partenza o il seguente classico fumetto xkcd .





oracle