15

默认情况下,Sqlite3 仅按 ascii 字母排序。我试图在谷歌中查找,但我发现的唯一内容是有关排序规则的信息。Sqlite3 只有NOCASE,RTRIMBIARY排序规则。如何添加对特定语言环境的支持?(我在 Rails 应用程序中使用它)

4

4 回答 4

27

我接受了 Doug Currie 的回答,但我想添加一些“算法”如何做到这一点,因为 sqlite3 文档非常奇怪(至少对我而言)。

好的,我们有工作 sqlite3 现在:

  1. 下载 sqlite 的 ICU 扩展

  2. 编译它:

    gcc -shared icu.c `icu-config --ldflags` -o libSqliteIcu.so
    

    它适用于 Linux。我还需要安装额外的 ICU 开发包:

    sudo apt-get install libicu-dev
    

    我正在研究 64 位架构,但我遇到了错误__relocation R_X86_64_32S__(无论它是什么意思 :)。GCC 建议添加-fPIC编译选项,它有所帮助。

  3. 运行 sqlite3。我们可以使用命令加载扩展:

    .load './libSqliteIcu.so'
    

    假设它在当前目录中,我们也可以指定整个路径。

  4. 创建新的排序规则:

    选择 icu_load_collat​​ion('pl_PL', 'POLISH');
    

    第一个参数是所需的语言环境,第二个参数是它(可以是任何东西)。

  5. 现在我们可以使用新的语言环境对数据进行排序:

    SELECT * FROM some_table ORDER BY name COLLATE POLISH;
    

    而且不区分大小写!

于 2009-03-05T15:32:42.780 回答
13

SQLite支持ICU集成。根据自述文件, sqlite/ext/icu/README.txtsqlite/ext/icu/目录包含 SQLite“ICU”扩展的源代码,它是“Unicode 国际组件”库与 SQLite 的集成。

1. Features

    1.1  SQL Scalars upper() and lower()
    1.2  Unicode Aware LIKE Operator
    1.3  ICU Collation Sequences
    1.4  SQL REGEXP Operator
于 2009-03-05T12:41:40.493 回答
2

如果你负担不起编译 ICU 扩展的费用,你可以让 UDF 做同样的事情。在 PHP/PDO 中:

$pdo->sqliteCreateFunction('locale',
    function ($data, $locale = 'root')
    {
        static $collators = array();

        if (isset($collators[$locale]) !== true)
        {
            $collators[$locale] = new \Collator($locale);
        }

        return $collators[$locale]->getSortKey($data);
    }
);

示例用法:

SELECT * FROM "table" ORDER BY locale("column", 'pt_PT');

我不希望这种方法与原生扩展一样高效,但它肯定更便携。

于 2013-09-01T23:59:24.327 回答
1

正如 Doug Currie 回答的那样,可以通过加载SQLite“ICU”扩展名来正确排序重音字符

需要编译扩展,如 kiew 自己的答案中所述。但是,ICU 自述文件和 kiew 的回答中给出的库名称对我不起作用。这个其他答案建议改用名称libicu.so

所以这就是在 Ubuntu 16.04 和 Debian 9.8 Stretch 上对我有用的方法:

sudo apt install libicu-dev libsqlite3-dev dpkg-dev gcc make
apt-get source sqlite3
cd sqlite3-*/ext/icu       # assuming you have only 1 sqlite3 source directory
gcc -shared icu.c `icu-config --ldflags` -fPIC -o libicu.so
sudo cp libicu.so /usr/local/lib/
sudo ldconfig

之后在 sqlite3 中,您可以

.load libicu
SELECT icu_load_collation('', 'ICU');

的 2 个参数icu_load_collation是语言环境和自定义名称。语言环境似乎是可选的,可以留空。然后可以看到自定义名称

PRAGMA collation_list;

它可以用作

SELECT col FROM tbl ORDER BY col COLLATE ICU;
于 2019-11-17T15:21:03.120 回答