開発用にローカルでMySQLデータベースを実行していますが、Postgresを使用するHerokuにデプロイしています。 Herokuはほとんどすべてを処理しますが、大文字と小文字を区別しないLikeステートメントは大文字と小文字を区別します。 iLikeステートメントを使用できますが、ローカルのMySQLデータベースはそれを処理できません。
MySQLとPostgresの両方と互換性がある、大文字と小文字を区別しないクエリを記述する最良の方法は何ですか?または、アプリが通信しているデータベースに応じて、LikeステートメントとiLikeステートメントを別々に記述する必要がありますか?
select * from foo where upper(bar) = upper(?);
呼び出し元でパラメーターを大文字に設定すると、2番目の関数呼び出しを回避できます。
この話の教訓は、開発と生産に異なるソフトウェアスタックを使用しないことです。決して。
あなたは、devで再現できないバグになってしまいます。あなたのテストは価値がないでしょう。しないでください。
別のデータベースエンジンを使用することは問題外です-LIKE以外の動作をするケースがはるかに多くあります(また、データベースで使用されている照合を確認しましたか?あらゆるケースで同じですか?同じ働きをするvarchar列のORDER BYを忘れる)
Arelを使用:
Author.where(Author.arel_table[:name].matches("%foo%"))
matches
はPostgresにILIKE
演算子を使用し、その他すべてにLIKE
演算子を使用します。
Postgresでは、これを行うことができます。
SELECT whatever FROM mytable WHERE something ILIKE 'match this';
MySQLに同等のものがあるかどうかはわかりませんが、これはいつでもできますが、少しwhichいですが、MySQLとpostgresの両方で動作するはずです。
SELECT whatever FROM mytable WHERE UPPER(something) = UPPER('match this');
いくつかの答えがありますが、どれも非常に満足のいくものではありません。
REGEXPは大文字と小文字を区別せず(BINARYと併用しない限り)、次のように使用できます。
SELECT id FROM person WHERE name REGEXP 'john';
...「John」、「JOHN」、「john」などに一致する.
PostgreSQL 8.4を使用している場合は、 citext モジュールを使用して、大文字と小文字を区別しないテキストフィールドを作成できます。
ブロック内のサブストリングを一致させたい場合は、postgresで〜*を使用することもできます。 〜は大文字と小文字を区別する部分文字列、〜*は大文字と小文字を区別しない部分文字列に一致します。操作は遅いですが、検索に役立つと思うかもしれません。
Select * from table where column ~* 'UnEvEn TeXt';
Select * from table where column ~ 'Uneven text';
両方が「ここに不均一なテキスト」にヒットします前者のみが「ここに不均一なテキスト」にヒットします
searchlogic プラグインをチェックアウトすることを検討することもできます。このプラグインは LIKE/ILIKE の切り替えを行います。
上位への変換は、最もよく使用される3つのRailsデータベースバックエンド。PostgreSQL、MySQL、およびSQLiteはすべてこの構文をサポートします。互換性のある構文をカバーします。アプリケーションまたは条件文字列で検索文字列を大文字にして、少し見栄えの悪いものにしますが、互換性を得ると価値があると思います。
MySQLとSQLite3の両方に、大文字と小文字を区別しないLIKE演算子があります。大文字と小文字を区別するLIKE演算子と、大文字と小文字を区別しない検索用のPostgreSQL固有の(マニュアルによる)ILIKE演算子は、PostgreSQLのみにあります。 Railsアプリケーションの条件でLIKEの内側にILIKEを指定できますが、アプリケーションはMySQLまたはSQLiteで動作しなくなることに注意してください。
3番目のオプションは、使用しているデータベースエンジンを確認し、それに応じて検索文字列を変更することです。これは、ActiveRecordの接続アダプターにハッキング/モンキーパッチを適用し、クエリ実行の前にPostgreSQLアダプターにクエリ文字列を変更して、「LIKE」を「ILIKE」に置き換えることにより、より適切に行うことができます。ただし、このソリューションは最も複雑であり、両方の用語を大文字にするなどの簡単な方法に照らして、これは努力する価値がないと思います(ただし、この方法で多くのブラウニーポイントを得ることができます)。