SQLite字符串比较上的本地化COLLATE

5 sqlite unicode

我想比较SQLite数据库中的两个字符串而不关心重音和大小写.我的意思是"Événement"应该等于"evenèment".

在Debian Wheezy上,SQLite包不提供ICU.所以我编译了包含ICU模块的官方SQLite包(版本3.7.15.2 2013-01-09 11:53:05).现在,我确实有更好的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)
Run Code Online (Sandbox Code Playgroud)

SQLite的文件证实,这是应用排序的正确方法.我认为这个ICU扩展文档有点轻松(很少的例子,没有关于整理的区分大小写).

我不明白为什么COLLATE操作符对我上面的例子没有影响.请帮忙.

小智 6

我把我的时间了解情况......在ICU归类是在SQLite的定义上比较有(几乎)没有发生率的方式.根据ICU的说法,例外情况是带有灌注标记的希伯来文本.这是ICU库的排序规则的默认行为.使用SQLite,LIKE在加载ICU时变得不区分大小写,但是不能通过这种方式实现加重字母的标准化.

我终于明白,我需要的是 将整理的强度设置 为 主要级别 而不是默认的高级级别.

我发现无法通过语言环境设置它(例如,几个变体SELECT icu_load_collation('fr_FR,strength=0', 'french')是无用的).所以唯一的解决方案就是修补SQLite的代码.感谢ICU API中ucol_setStrength()功能.

最小的变化是单行补丁:在函数ucol_setStrength(pUCollator, 0);后添加行.用于向后兼容的改变,我增加一个可选的第三个参数,设定强度:0为默认,1为伯,等等,直到4季.看看差异.pUCollator = ucol_open(zLocale, &status);icuLoadCollation()icu_load_collation()

最后我有我想要的东西:

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