PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Escape-SQL-LIKE-Wert für Postgres mit psycopg2

Ja, das ist eine echte Sauerei. Sowohl MySQL als auch PostgreSQL verwenden dafür standardmäßig Backslash-Escapes. Dies ist ein schrecklicher Schmerz, wenn Sie die Zeichenfolge auch wieder mit Backslashes maskieren, anstatt die Parametrisierung zu verwenden, und es ist auch falsch gemäß ANSI SQL:1992, das besagt, dass es standardmäßig keine zusätzlichen Escape-Zeichen zusätzlich zur normalen Zeichenfolgen-Escapezeichen gibt, und daher keine Möglichkeit, einen wörtlichen % einzufügen oder _ .

Ich würde vermuten, dass die einfache Backslash-Replace-Methode auch schief geht, wenn Sie die Backslash-Escapes (die selbst nicht mit ANSI SQL kompatibel sind) mit NO_BACKSLASH_ESCAPE deaktivieren sql_mode in MySQL oder standard_conforming_strings conf in PostgreSQL (womit die PostgreSQL-Entwickler schon seit einigen Versionen drohen).

Die einzig wirkliche Lösung ist die Verwendung des wenig bekannten LIKE...ESCAPE Syntax, um ein explizites Escape-Zeichen für LIKE anzugeben -Muster. Dies wird anstelle des Backslash-Escape in MySQL und PostgreSQL verwendet, wodurch sie mit dem übereinstimmen, was alle anderen tun, und eine garantierte Möglichkeit bieten, die Out-of-Band-Zeichen einzuschließen. Zum Beispiel mit dem = Zeichen als Escapezeichen:

# 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+'%'))

Dies funktioniert auf PostgreSQL-, MySQL- und ANSI-SQL-kompatiblen Datenbanken (modulo paramstyle natürlich, der sich auf verschiedenen DB-Modulen ändert).

Möglicherweise gibt es noch ein Problem mit MS SQL Server/Sybase, der anscheinend auch [a-z] erlaubt -Stil-Zeichengruppen in LIKE Ausdrücke. In diesem Fall möchten Sie auch das Literal [ maskieren Zeichen mit .replace('[', '=[') . Laut ANSI SQL ist es jedoch ungültig, ein Zeichen zu maskieren, das nicht maskiert werden muss! (Argh!) Obwohl es wahrscheinlich immer noch über echte DBMSs funktionieren wird, wären Sie immer noch nicht ANSI-konform. seufz...