ios - FMDB:SQLite 语句 ORDER BY 命令变音符号不正确

标签 ios sqlite swift xcode6 fmdb

我是 iOS 开发的新手,有很多东西需要学习。它就像一座大山,但多亏了你的帮助,我才找到了位置;)

我已经启动了一个 Xcode 项目(Xcode 版本 6.1.1、Swift、iOS)并包含了 FMDB 以运行 SQLite 查询。查询执行得很好,但是在以下语句中:

var resultSet: FMResultSet! = sharedInstance.database!.executeQuery("SELECT * FROM spesenValues ORDER BY country ASC", withArgumentsInArray: nil)

从我的角度来看,字母顺序是错误的,但我似乎不知道如何解决它。标准的 A-Z 字符被排序到我期望的位置,但是任何包含变音符号的字符,例如ÄÖÜ 排在列表的最底部。

所以我期望的是:

奥地利 ... 塞浦路斯

但是我得到的是

Zypern ... 奥地利

来自 SQLite Order By places umlauts & speical chars at end我了解到这是因为“iOS 上的 SQLite 没有启用 ICU”这一事实。

有没有一种简单的方法来配置 FMDB 来帮助我“正确”排序。在此先感谢您,如果这变成了一个 super 愚蠢的问题,我们深表歉意

最佳答案

您可以定义自己的 SQLite 函数,该函数使用 CFStringTransform 来删除重音符号。使用 FMDB 2.7:

db.makeFunctionNamed("unaccented", arguments: 1) { context, argc, argv in
    guard db.valueType(argv[0]) == .text || db.valueType(argv[0]) == .null else {
        db.resultError("Expected string parameter", context: context)
        return
    }

    if let string = db.valueString(argv[0])?.folding(options: .diacriticInsensitive, locale: nil) {
        db.resultString(string, context: context)
    } else {
        db.resultNull(context: context)
    }
}

然后您可以在 SQL 中使用这个新的 unaccented 函数:

do {
    try db.executeQuery("SELECT * FROM spesenValues ORDER BY unaccented(country) ASC" values: nil) 

    while rs.next() {
        // do what you want with results
    }

    rs.close()
} else {
    NSLog("executeQuery error: %@", db.lastErrorMessage())
}

您建议将“ä”、“ö”和“ü”分别替换为“ae”、“oe”和“ue”。这通常只用专有名称和地理名称完成(参见维基百科的 German orthography 条目),但如果你想这样做,让你的自定义函数(我已重命名为“sortstring”)适本地替换这些值:

db.makeFunctionNamed("sortstring", arguments: 1) { context, argc, argv in
    guard argc == 1 && (db.valueType(argv[0]) == .text || db.valueType(argv[0]) == .null) else {
        db.resultError("Expected string parameter", context: context)
        return
    }

    let replacements = ["ä": "ae", "ö": "oe", "ü": "ue", "ß": "ss"]

    var string = db.valueString(argv[0])!.lowercased()

    for (searchString, replacement) in replacements {
        string = string.replacingOccurrences(of: searchString, with: replacement)
    }

    db.resultString(string.folding(options: .diacriticInsensitive, locale: nil), context: context)
}

顺便说一下,由于您只是将其用于排序,因此您可能还想将其转换为小写,这样大写值就不会与小写值分开。

但是思路是一样的,定义任何你想要排序的函数,然后你可以使用 FMDB 的 makeFunctionNamed 让它在 SQLite 中可用。

关于ios - FMDB:SQLite 语句 ORDER BY 命令变音符号不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27572063/

相关文章:

ios - 如何在 UIDatePicker 中禁用 future 的日期、月份和年份?

android - 存储在android sqlite数据库中的数据的生命周期是多少

swift - 多个重叠 View

ios - 在表格 View 中对歌曲名称进行排序 - Swift

ios - 在 TableView 单元格 swift 3 中添加 Collection View

ios - 应用程序试图在目标 <UINavigationController> mapkit 公开按钮上推送一个 nil View Controller

iphone - 如何让 UIPickerview 适应屏幕大小?

ios - Audiokit 4.5.2 - 无法通过终端中的 cocoa pod 安装

mysql - 如何将数组插入sqlitedatabase列以及如何在Uitableview单元格中显示

java - 调用sqlite onUpgrade问题