PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Échapper à la valeur SQL LIKE pour Postgres avec psycopg2

Oui, c'est un vrai gâchis. MySQL et PostgreSQL utilisent tous deux des échappements antislash pour cela par défaut. C'est une douleur terrible si vous échappez à nouveau la chaîne avec des barres obliques inverses au lieu d'utiliser le paramétrage, et c'est également incorrect selon ANSI SQL:1992, qui dit qu'il n'y a par défaut aucun caractère d'échappement supplémentaire en plus de la chaîne normale s'échappant, et donc aucun moyen d'inclure un % littéral ou _ .

Je suppose que la méthode simple de remplacement de la barre oblique inverse échoue également si vous désactivez les échappements par barre oblique inverse (qui ne sont pas conformes à ANSI SQL), en utilisant NO_BACKSLASH_ESCAPE sql_mode dans MySQL ou standard_conforming_strings conf dans PostgreSQL (ce que les développeurs de PostgreSQL menacent de faire depuis quelques versions maintenant).

La seule vraie solution est d'utiliser le peu connu LIKE...ESCAPE syntaxe pour spécifier un caractère d'échappement explicite pour le LIKE -modèle. Ceci est utilisé à la place de l'échappement par barre oblique inverse dans MySQL et PostgreSQL, ce qui les rend conformes à ce que tout le monde fait et donne un moyen garanti d'inclure les caractères hors bande. Par exemple avec le = signe comme échappement :

# 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 les bases de données PostgreSQL, MySQL et ANSI SQL (modulo le paramstyle bien sûr qui change sur différents modules db).

Il peut toujours y avoir un problème avec MS SQL Server/Sybase, qui autorise apparemment aussi [a-z] -groupes de caractères de style dans LIKE expressions. Dans ce cas, vous voudriez également échapper le littéral [ caractère avec .replace('[', '=[') . Cependant, selon ANSI SQL, échapper un caractère qui n'a pas besoin d'être échappé n'est pas valide ! (Argh!) Donc, même si cela fonctionnera probablement toujours sur de vrais SGBD, vous ne serez toujours pas conforme à la norme ANSI. soupir...