ええ、これは本当の混乱です。デフォルトでは、MySQL と PostgreSQL の両方でバックスラッシュ エスケープが使用されます。パラメータ化を使用する代わりにバックスラッシュを使用して文字列を再度エスケープしている場合、これはひどい痛みです。また、ANSI SQL:1992 によると、これは正しくありません。これは、デフォルトでは、通常の文字列エスケープの上に余分なエスケープ文字がないことを示しています。したがって、リテラル%
またはを含める方法はありません_
。
NO_BACKSLASH_ESCAPE
MySQL で sql_mode を使用するかstandard_conforming_strings
、PostgreSQL で confを使用してバックスラッシュエスケープ (ANSI SQL に準拠していない) をオフにすると、単純なバックスラッシュ置換メソッドもうまくいかないと思います(PostgreSQL 開発者はこれを行うと脅しています)。現在、いくつかのバージョンがあります)。
唯一の本当の解決策は、ほとんど知られていない構文を使用して、 -patternLIKE...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]
は、式で -style 文字グループも使用できるようLIKE
です。この場合、リテラル[
文字も でエスケープする必要があり.replace('[', '=[')
ます。ただし、ANSI SQL によると、エスケープする必要のない文字のエスケープは無効です。(うーん!) したがって、実際の DBMS で動作する可能性はありますが、ANSI に準拠しているとは言えません。はぁ...