ええ、これは本当の混乱です。 MySQLとPostgreSQLはどちらも、デフォルトでこれにバックスラッシュエスケープを使用します。パラメータ化を使用する代わりにバックスラッシュを使用して文字列を再度エスケープする場合、これはひどい苦痛です。また、ANSI SQL:1992によると、通常の文字列エスケープの上に余分なエスケープ文字がないことを示しています。したがって、リテラルの%
を含める方法はありません。 または_
。
NO_BACKSLASH_ESCAPE
を使用してバックスラッシュエスケープ(それ自体はANSI SQLに準拠していません)をオフにすると、単純なバックスラッシュ置換メソッドも失敗すると思います。 MySQLのsql_modeまたはstandard_conforming_strings
PostgreSQLでのconf(PostgreSQL開発者は現在いくつかのバージョンで行うと脅迫しています)。
唯一の実際の解決策は、あまり知られていないLIKE...ESCAPE
を使用することです。 LIKE
の明示的なエスケープ文字を指定する構文 -パターン。これは、MySQLとPostgreSQLのバックスラッシュエスケープの代わりに使用され、他のすべてのユーザーが行うことと一致し、帯域外文字を含めることが保証されます。たとえば、=
を使用します エスケープとして署名する:
# 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+'%'))
これは、PostgreSQL、MySQL、およびANSI SQL準拠のデータベースで機能します(もちろん、さまざまなdbモジュールで変更されるparamstyleを法として)。
MS SQL Server / Sybaseにはまだ問題がある可能性があります。これにより、[a-z]
も許可されるようです。 LIKE
のスタイルの文字グループ 式。この場合、リテラルの[
もエスケープする必要があります .replace('[', '=[')
の文字 。ただし、ANSI SQLによると、エスケープする必要のない文字をエスケープすることは無効です。 (ああ!)したがって、実際のDBMSでも機能する可能性がありますが、ANSIに準拠しているとは限りません。ため息...