Sí, esto es un verdadero desastre. Tanto MySQL como PostgreSQL usan escaneos de barra invertida para esto de manera predeterminada. Esto es un dolor terrible si también está escapando de nuevo con cadenas en lugar de utilizar la parametrización, y también es incorrecto de acuerdo con ANSI SQL: 1992, que dice que de manera predeterminada no hay caracteres de escape adicionales sobre el escape de cadena normal, y por lo tanto, no hay manera de incluir un literal %
o _
.
que presumiría el método simple barra invertida-sustituir también va mal si se apaga la barra invertida se escapa (que son ellos mismos no cumplen con las normas ANSI SQL), utilizando NO_BACKSLASH_ESCAPE
sql_mode en MySQL o standard_conforming_strings
conf en PostgreSQL (que el PostgreSQL los desarrolladores han amenazado con hacer un par de versiones ahora).
La única solución real es utilizar la sintaxis LIKE...ESCAPE
poco conocida para especificar un carácter de escape explícito para LIKE
-pattern. Esto se usa en lugar del escape de barra invertida en MySQL y PostgreSQL, haciéndolos ajustarse a lo que hacen todos los demás y dando una forma garantizada de incluir los caracteres fuera de banda. Por ejemplo con el signo =
como un escape:
# look for term anywhere within title
term= term.replace('=', '==').replace('%', '=%').replace('_', '=_')
sql= "SELECT * FROM things WHERE description LIKE %(like)s ESCAPE '='"
cursor.execute(sql, dict(like= '%'+term+'%'))
Esto funciona en PostgreSQL, MySQL, y bases de datos SQL-compatible con ANSI (módulo el paramstyle por supuesto que cambia en diferentes módulos dB).
Todavía puede haber un problema con MS SQL Server/Sybase, que aparentemente también permite [a-z]
-style grupos de caracteres en expresiones LIKE
. En este caso, también desearía escapar del carácter literal [
con .replace('[', '=[')
. Sin embargo, según ANSI SQL escapando, un personaje que no necesita escaparse no es válido. (Argh!) Entonces, aunque probablemente funcione en DBMS reales, aún no cumplirás con ANSI. suspiro ...
has olvidado "'" y' "' –
@JensTimmerman esta función solo escapa a los tokens similares, para usar la cadena normal que escapa del resultado antes de usarlo en una consulta. El escape de cadena correcto depende del sessing' standard_conforming_stings' y por lo tanto, lo mejor es usar el código de la biblioteca. – Jasen