我需要执行对大小写和重音不敏感的 SELECT 查询。出于演示目的,我创建了一个这样的表:
create table table
(
column text collate nocase
);
insert into table values ('A');
insert into table values ('a');
insert into table values ('Á');
insert into table values ('á');
create index table_cloumn_Index
on table (column collate nocase);
然后,我在执行以下查询时得到这些结果:
SELECT * FROM table WHERE column LIKE 'a';
> A
> a
SELECT * FROM table WHERE column LIKE 'á';
> á
SELECT * FROM table WHERE column LIKE 'Á';
> Á
我怎样才能解决这个问题,使以下任何查询的结果都像这样:
> A
> a
> Á
> á
顺便说一下,sqlite 在 iOS 上运行。
提前致谢
最佳答案
两种基本方法:
您可以在表中创建第二列,其中包含不含国际字符的字符串。此外,在针对此辅助搜索列进行搜索之前,您还应该从正在搜索的字符串中删除国际字符(这样您就可以将非国际字符与非国际字符进行比较)。
这是我用来转换国际字符的例程:
NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
您还可以将重音字符替换为:
NSMutableString *mutableString = [string mutableCopy]; CFStringTransform((__bridge CFMutableStringRef)mutableString, NULL, kCFStringTransformStripCombiningMarks, NO);
顺便说一下,如果您需要对结果进行排序,您也可以根据这个辅助搜索字段而不是主字段进行排序,这也可以避免 SQLite 无法对国际字符进行排序的问题。
您也可以创建自己的“无重音”C 函数(在您的类的
@implementation
之外定义此 C 函数):void unaccented(sqlite3_context *context, int argc, sqlite3_value **argv) { if (argc != 1 || sqlite3_value_type(argv[0]) != SQLITE_TEXT) { sqlite3_result_null(context); return; } @autoreleasepool { NSMutableString *string = [NSMutableString stringWithUTF8String:(const char *)sqlite3_value_text(argv[0])]; CFStringTransform((__bridge CFMutableStringRef)string, NULL, kCFStringTransformStripCombiningMarks, NO); sqlite3_result_text(context, [string UTF8String], -1, SQLITE_TRANSIENT); } }
然后你可以定义一个调用这个C函数的SQLite函数(打开数据库后调用这个方法,直到你关闭数据库才会生效):
- (void)createUnaccentedFunction { if (sqlite3_create_function_v2(database, "unaccented", 1, SQLITE_ANY, NULL, &unaccented, NULL, NULL, NULL) != SQLITE_OK) NSLog(@"%s: sqlite3_create_function_v2 error: %s", __FUNCTION__, sqlite3_errmsg(database)); }
完成后,您现在可以在 SQL 中使用这个新的
unaccented
函数,例如:if (sqlite3_prepare_v2(database, "select a from table where unaccented(column) like 'a'", -1, &statement, NULL) != SQLITE_OK) NSLog(@"%s: insert 1: %s", __FUNCTION__, sqlite3_errmsg(database));
关于ios - 如何处理 iOS SQLite 中的重音字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10356062/