【问题标题】:Use of sqlite3_create_collation on iPhone在 iPhone 上使用 sqlite3_create_collat​​ion
【发布时间】:2013-01-19 06:25:52
【问题描述】:

我想创建一个排序规则,以便在数据库中不区分大小写并且没有重音搜索。

这是我的代码:

static int sqlite3NoCaseNoAccentCollate(void * foo, int ll, const void *l, int rl,
                         const void *r){
    NSLog(@"comparing");
    NSString *left = [NSString stringWithCharacters:l length:ll];
    NSString *right = [NSString stringWithCharacters:r length:rl];
    NSComparisonResult rs = [left compare:right options:NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch|NSForcedOrderingSearch];

    NSLog("%d",rs);
    return rs;
}


sqlite3 *db;
if (SQLITE_OK==sqlite3_open([pathToDataBase UTF8String], &db)){
    sqlite3_create_collation(db, "MYNOCASENOACCENT", SQLITE_UTF8, NULL, &sqlite3NoCaseNoAccentCollate);
}

当我执行这个查询时:

SELECT ('teste' LIKE 'testé' COLLATE MYNOCASENOACCENT)

它返回 0 而不是 1,并且我的自定义函数永远不会被调用(我在函数中放置断点进行测试)。

当我使用“PRAGMA collat​​ion_list”列出所有排序规则时,我的自定义排序规则存在。

你知道这个问题吗?

【问题讨论】:

  • stringWithCharacters:length: 需要一个 unichar(又名 UTF-16)字符串。您可能必须使用initWithBytes:length:encoding: 并指定NSUTF8StringEncoding。 - 但是,如果根本不调用比较函数,这可能无法解决您的问题。
  • 是的,对于“stringWithCharacters”我将使用“stringWithUTF8String”,它更简单。就像你说的,这不是真正的问题:)
  • 请注意,stringWithUTF8String 只能在字符串以 NULL 结尾的情况下使用。您可能必须明确指定长度。
  • 你可以试试SQLITE_UTF16而不是SQLITE_UTF8(和stringWithCharacters:length:在比较函数中)。

标签: iphone objective-c sqlite accent-insensitive


【解决方案1】:

可能为时已晚,所以就简单介绍一下:

您定义了排序规则函数。将用于比较指定排序规则的表列。如您所见,它不会应用于 like 运算符。

你需要做的是定义和注册一个like函数,例如

static void utf8likeFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
{
    //...
}

sqlite3_create_function(db, "like", 2, SQLITE_UTF8, (void*)&likeInfoNorm, utf8likeFunc, 0, 0);

类似函数的示例可以在 sqlite 源代码中找到。

【讨论】:

  • 我验证这个答案是因为我相信它,但我没有时间测试它。感谢这个解决方案,我稍后会研究它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-02
  • 2017-07-28
  • 1970-01-01
  • 1970-01-01
  • 2022-07-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多