2008-08-27 19 views
11

Tengo una base de datos con nombres como John Doe, etc. Desafortunadamente, algunos de estos nombres contienen citas como Keiran O'Keefe. Ahora cuando trato de buscar nombres como los siguientes:¿Cómo trato las cotizaciones? En SQL

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

I (comprensiblemente) me sale un error.

¿Cómo puedo prevenir este error? Estoy usando Oracle y PLSQL.

+0

Ver [** cadena literal para Citando técnica de marcas de una sola cotización **] (http://lalitkumarb.com/2014/12/31/quoting-string-literal-technique-to-avoid-erros -due-to-single-quotation-marks-in-the-string /) –

Respuesta

30

El carácter de escape es ', por lo que tendría que reemplazar la cita con dos comillas.

Por ejemplo,

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

convierte

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

Dicho esto, es probablemente incorrecta de hacer esto por sí mismo. Su lenguaje puede tener una función para escapar cadenas para usar en SQL, pero una opción aún mejor es usar parámetros. Por lo general, esto funciona de la siguiente manera.

Su comando SQL sería:

SELECT * FROM PEOPLE WHERE SURNAME=?

Entonces, cuando lo ejecutas, se pasa en "O'Keefe" como parámetro.

Como SQL se analiza antes de establecer el valor del parámetro, no hay forma de que el valor del parámetro altere la estructura del SQL (y es incluso más rápido si se quiere ejecutar la misma instrucción varias veces con diferentes parámetros)

Debo señalar también que, si bien su ejemplo solo causa un error, usted se abre a muchos otros problemas al no escapar de las cadenas adecuadamente. Consulte http://en.wikipedia.org/wiki/SQL_injection para obtener un buen punto de partida o el siguiente clásico xkcd comic.

alt text

+0

+1 para recomendar variables de vinculación. Si usas variables de vinculación, estas cosas molestas nunca ocurren, y tus consultas son mejores, y no estás abierto a los ataques de inyección de SQL. –

+0

Muchas gracias, acabas de salvar mi día :). Ojalá pueda +2 a estas publicaciones. Niza de dibujos animados también :) –

0

Los filtros de entrada se hace generalmente en el nivel de idioma en lugar de capas de base de datos.
php y .NET tienen sus respectivas bibliotecas para escapar de las sentencias SQL. Verifique su idioma, vea lo que está disponible.
Si sus datos son confiables, entonces puede simplemente reemplazar una cadena para agregar otra 'delante de' para escapar. Por lo general, eso es suficiente si no hay riesgos de que la entrada sea maliciosa.

1

Supongo que una buena pregunta es qué idioma estás usando?
En PHP harías: SELECCIONAR * FROM PEOPLE WHERE SURNAME = 'mysql_escape_string (O'Keefe)'
Pero como no especificaste el idioma, te sugiero que busques una función de cadena de escape mysql o de lo contrario en tu idioma.

+0

'mysqli_real_escape_string()' para un enfoque más actualizado. – Jordan

1

consultas con parámetros son de su amigo, según lo sugerido por Matt.

Command = SELECT * FROM PEOPLE WHERE SURNAME=? 

Ellos le protegerá de los dolores de cabeza que participan en

  • Cuerdas con citas
  • Consulta utilizando fechas
  • inyección SQL
1

El uso de SQL parametrizada tiene otros beneficios, reduce la sobrecarga de la CPU (así como otros recursos) en Oracle al reducir la cantidad de trabajo que Oracle requiere con el fin de analizar la declaración. Si no usa parámetros (los llamamos variables de enlace en Oracle), entonces "select * from foo where bar = 'cat'" y "select * from foo donde bar = 'dog'" se tratan como declaraciones separadas, donde como " select * from foo donde bar =: b1 "es la misma instrucción, lo que significa cosas como sintaxis, validez de objetos a los que se hace referencia, etc. ... no es necesario volver a verificarlos. Hay problemas ocasionales que surgen cuando se utilizan variables de vinculación que generalmente se manifiestan al no obtener el plan de ejecución de SQL más eficiente, pero existen soluciones para esto y estos problemas realmente dependen de los predicados que está utilizando, indexación y sesgo de datos.

3

Oracle 10 solución es

SELECT * FROM PEOPLE WHERE SURNAME=q'{O'Keefe}' 
+0

voto a favor. Incluso con Oracle, debe usar consultas parametrizadas. –

0

Para hacer frente comillas si usted está usando Zend Framework Este es el código

$db = Zend_Db_Table_Abstract::getDefaultAdapter();

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

por ejemplo;

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