Pregunta

Esta pregunta ya tiene respuesta aquí:

Tengo una base de datos con nombres como John Doe, etc.Lamentablemente algunos de estos nombres contienen citas como Keiran O'Keefe.Ahora, cuando intento buscar esos nombres de la siguiente manera:

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

(Comprensiblemente) recibo un error.

¿Cómo evito que ocurra este error?Estoy usando Oracle y PLSQL.

¿Fue útil?

Solución

El carácter de escape es ', por lo que deberá reemplazar la comilla con dos comillas.

Por ejemplo,

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

se convierte

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

Dicho esto, probablemente sea incorrecto hacerlo usted mismo.Es posible que su idioma tenga una función para escapar de cadenas para usar en SQL, pero una opción aún mejor es usar parámetros.Normalmente esto funciona de la siguiente manera.

Su comando SQL sería:

SELECT * FROM PEOPLE WHERE SURNAME=?

Luego, cuando lo ejecutas, pasas "O'Keefe" como parámetro.

Debido a que el 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 (e incluso es un poco más rápido si desea ejecutar la misma declaración varias veces con diferentes parámetros).

También debo señalar que, si bien su ejemplo solo causa un error, se expone a muchos otros problemas al no escapar las cadenas de manera adecuada.Ver http://en.wikipedia.org/wiki/SQL_injection para un buen punto de partida o el siguiente clásico comic xkcd.

alt text

Otros consejos

La solución Oracle 10 es

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

Las consultas parametrizadas son tus amigas, como sugiere Matt.

Command = SELECT * FROM PEOPLE WHERE SURNAME=?

Te protegerán de los dolores de cabeza relacionados con

  • Cadenas con comillas
  • Consultar usando fechas
  • Inyección SQL

El uso de SQL parametrizado tiene otros beneficios: reduce la sobrecarga de la CPU (así como otros recursos) en Oracle al reducir la cantidad de trabajo que Oracle requiere para analizar la declaración.Si no utiliza parámetros (los llamamos variables de enlace en Oracle), entonces "select * from foo donde bar='cat'" y "select * from foo donde bar='dog'" se tratan como declaraciones separadas, mientras que " select * from foo donde bar=:b1" es la misma declaración, lo que significa que cosas como la sintaxis, la validez de los objetos a los que se hace referencia, etc., no es necesario verificarlas nuevamente.Hay problemas ocasionales que surgen al usar 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, la indexación y la desviación de los datos.

El filtrado de entrada generalmente se realiza a nivel de idioma en lugar de capas de base de datos.
Tanto php como .NET tienen sus respectivas bibliotecas para escapar de declaraciones SQL.Verifique su idioma, vea lo que está disponible.
Si sus datos son confiables, entonces puede simplemente reemplazar una cadena para agregar otro 'delante de' para escapar de ellos.Por lo general, esto es suficiente si no hay riesgo de que la entrada sea maliciosa.

Supongo que una buena pregunta es ¿qué idioma estás usando?
En PHP harías:SELECCIONE * DE LAS PERSONAS DONDE APELLIDO='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 otro modo en tu idioma.

Para gestionar cotizaciones si está utilizando Zend Framework, aquí está 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\''

Encontrado en menores de 30 años en Google...

Preguntas frecuentes sobre SQL de Oracle

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top