Oui, c'est un vrai bordel. MySQL et PostgreSQL utilisent des backslash-escape pour cela par défaut. C'est une douleur terrible si vous échappez à nouveau à la chaîne avec des antislashs au lieu d'utiliser le paramétrage, et c'est aussi incorrect selon ANSI SQL: 1992, qui dit qu'il n'y a pas de caractères d'échappement supplémentaires par défaut. donc aucun moyen d'inclure un littéral %
ou _
.
Je présume la méthode simple de antislash remplacer va aussi mal si vous désactivez la barre oblique inverse-échappements (qui sont eux-mêmes non conformes à la norme ANSI SQL), en utilisant NO_BACKSLASH_ESCAPE
sql_mode dans MySQL ou standard_conforming_strings
conf dans PostgreSQL (qui PostgreSQL les développeurs ont menacé de le faire pour quelques versions maintenant).
La seule solution réelle consiste à utiliser la syntaxe peu connue LIKE...ESCAPE
pour spécifier un caractère d'échappement explicite pour le modèle LIKE
. Ceci est utilisé à la place du backslash-escape dans MySQL et PostgreSQL, ce qui les rend conformes à ce que tout le monde fait et donne une garantie d'inclure les caractères hors-bande. Par exemple avec le signe =
comme une évasion:
# 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+'%'))
Cela fonctionne sur PostgreSQL, MySQL et ANSI bases de données SQL conformes (modulo le paramstyle bien sûr qui change sur les différents modules db).
Il se peut qu'il y ait toujours un problème avec MS SQL Server/Sybase, qui semble également autoriser les groupes de caractères [a-z]
dans les expressions LIKE
. Dans ce cas, vous voudriez également échapper le caractère littéral [
avec .replace('[', '=[')
. Cependant selon ANSI SQL s'échapper un caractère qui n'a pas besoin d'échapper est invalide! (Argh!) Donc, même si cela fonctionnera probablement encore sur de vrais SGBD, vous ne seriez toujours pas conforme à ANSI. soupir ...
Vous avez oublié "'" et' "' –
@JensTimmerman Cette fonction n'échappe qu'aux jetons similaires, pour utiliser la chaîne normale qui s'échappe sur le résultat avant de l'utiliser dans une requête, la chaîne correcte s'échappe dépend du paramètre' standard_conforming_stings' et il est le mieux fait en utilisant le code de la bibliothèque. – Jasen