使用SQL ILIKE查询土耳其字符‘ı’和‘I’时无法得到预期结果
解决PostgreSQL中土耳其语字母'i'/'ı'的大小写匹配问题
问题根源
PostgreSQL的ilike操作依赖**排序规则(Collation)**处理大小写转换,默认排序规则不会识别土耳其语中I→ı、i→İ的特殊映射关系,导致跨大小写匹配失败。
解决方案
1. 检查当前排序规则
先确认目标列或数据库使用的排序规则:
-- 检查surname列的排序规则 SELECT collation FROM information_schema.columns WHERE table_name = 'drivers' AND column_name = 'surname'; -- 检查数据库默认排序规则 SELECT datcollate FROM pg_database WHERE datname = '你的数据库名';
如果结果不是土耳其语相关的排序规则(如tr_TR.utf8或tr-TR-x-icu),就需要调整。
2. 修改列的默认排序规则(推荐)
直接修改surname列的排序规则为土耳其语,后续所有匹配操作都会自动适配:
-- 使用系统自带的土耳其语排序规则 ALTER TABLE drivers ALTER COLUMN surname TYPE text COLLATE "tr_TR.utf8"; -- 或使用更完善的ICU排序规则(PostgreSQL 10+支持) ALTER TABLE drivers ALTER COLUMN surname TYPE text COLLATE "tr-TR-x-icu";
修改后,原ilike查询无需改动即可正确匹配akın和AKIN这类大小写变体。
3. 查询时临时指定排序规则
如果无法修改表结构,可在查询中临时指定土耳其语排序规则:
SELECT * FROM drivers d WHERE d.surname COLLATE "tr_TR.utf8" ILIKE CONCAT('%', $2::text, '%') COLLATE "tr_TR.utf8";
或者简化为只给列指定排序规则(PostgreSQL会自动对齐匹配项的规则):
SELECT * FROM drivers d WHERE d.surname COLLATE "tr_TR.utf8" ILIKE CONCAT('%', $2::text, '%');
4. 验证匹配效果
执行以下测试语句确认规则生效:
-- 验证AKIN匹配akın SELECT 'AKIN' ILIKE '%akın%' COLLATE "tr_TR.utf8"; -- 应返回true -- 验证akın匹配AKIN SELECT 'akın' ILIKE '%AKIN%' COLLATE "tr_TR.utf8"; -- 应返回true
内容的提问来源于stack exchange,提问作者Caner Altug Demirkan
相关产品推荐
相关产品推荐

