2013-02-24 7 views
5

アクセントと大文字小文字を区別せずにSQLite DBの2つの文字列を比較したいと思います。私は "Événement"が "evenement"に等しいはずであることを意味します。SQLite文字列比較のローカライズされたCOLLATE

Debian Wheezyでは、SQLiteパッケージはICUを提供しません。そこで私は公式のSQLiteパッケージ(バージョン3.7.15.2 2013-01-09 11:53:05)をコンパイルし、ICUモジュールを含んでいます。さて、私はより良いUnicodeサポートを持っています(元のlower()はASCII文字にのみ適用され、今は他の文字でも機能します)。しかし、比較に照合を適用することはできません。

SELECT icu_load_collation('fr_FR', 'FRENCH'); 
SELECT 'événement' COLLATE FRENCH = 'evenement'; 
-- 0 (should be 1) 
SELECT 'Événement' COLLATE FRENCH = 'événement'; 
-- 0 (should be 1 if collation was case-insensitive) 
SELECT lower('Événement') = 'événement'; 
-- 1 (at least lower() works as expected with Unicode strings) 

SQLite documentationは、これが照合を適用する正しい方法であることを確認します。私はdocumentation of this ICU extensionが少し明るいと思っています(いくつかの例では、照合の大文字と小文字の区別はありません)。

COLLATE演算子が上記の例で効果がない理由を理解できません。助けてください。

答えて

5

私は状況を理解するのに何時間もかかりました... ICUの照合順序がSQLiteで定義されている方法は、(ほとんど)比較にはありません。例外は、ICUによると、ヘブライ語の文章にはカンティレーションマークが付いています。これは、ICUライブラリの照合のデフォルト動作です。 SQLiteでは、LIKEはICUが読み込まれたときに大文字と小文字を区別しないようになりますが、強調された文字の正規化はこの方法では達成できません。

は、私は最終的に私が必要とする代わりに、デフォルトの高等教育レベルの primary level に照合の strength を設定したことを理解しました。

これをロケール で設定する方法が見つかりませんでした(たとえば、SELECT icu_load_collation('fr_FR,strength=0', 'french')のいくつかの変種は役に立たなかった)。 唯一の解決策は、SQLiteのコードを修正することでした。 ICU APIucol_setStrength()ファンクション のおかげで簡単でした。

最小限の変更は1行のパッチです。icuLoadCollation()pUCollator = ucol_open(zLocale, &status);の後に行ucol_setStrength(pUCollator, 0);を追加してください。 下位互換性のある変更のために、私は強度を設定するicu_load_collation()にオプションの第3のパラメータを追加しました:デフォルトでは 、プライマリでは1、それ以外は4-fouraternaryまでです。 diffを参照してください。最後に

私が欲しかったものを持っている:

SELECT icu_load_collation('fr_FR', 'french_ci', 1); -- collation with strength=primary 
SELECT 'Événement' COLLATE french_ci = 'evenèment'; 
-- 1