如何使用指定的语言环境对 sqlite3 中的文本进行排序?

Posted

技术标签:

【中文标题】如何使用指定的语言环境对 sqlite3 中的文本进行排序?【英文标题】:How to sort text in sqlite3 with specified locale? 【发布时间】:2010-10-11 07:40:49 【问题描述】:

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

【问题讨论】:

【参考方案1】:

正如 Doug Currie 回答的那样,可以通过加载 SQLite "ICU" extension 来正确排序重音字符

需要编译扩展,如 kiew 自己的回答中所述。但是,ICU 自述文件和 kiew 的回答中给出的库名称对我不起作用。 This other answer 建议改用名称 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');

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

PRAGMA collation_list;

而且可以像在中那样使用

SELECT col FROM tbl ORDER BY col COLLATE ICU;

【讨论】:

【参考方案2】:

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

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

    Download ICU extension for sqlite

    编译:

    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,这很有帮助。

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

    .load './libSqliteIcu.so'

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

    创建新的排序规则:

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

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

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

    SELECT * FROM some_table ORDER BY name COLLATE POLISH;

    而且不区分大小写!

【讨论】:

我未能在 macOS 10.13 上构建它。对于我可以谷歌搜索的所有文件,它们似乎都已经过时了。 安装ICU和SQLite3开发包sudo apt update && sudo apt install libicu-dev libsqlite3-dev -y 谢谢。这真的很有帮助,即使它没有立即起作用。 .load libSqliteIcu 会给Error: /usr/local/lib/libSqliteIcu.so: undefined symbol: sqlite3_sqliteicu_init。将名称更改为libicu.so 后,它可以工作。附加答案中的详细信息。【参考方案3】:

SQLite supports 与 ICU 集成。根据自述文件, sqlite/ext/icu/README.txt sqlite/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

【讨论】:

第一个链接现在受密码保护。【参考方案4】:

如果您负担不起编译 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');

我不认为这种方法会像原生扩展一样高效,但它肯定更便携。

【讨论】:

以上是关于如何使用指定的语言环境对 sqlite3 中的文本进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

易语言如何取剪切板中的部分文本?

C++ 使用 SQLite3 ,打开指定数据库,执行插入操作后会啥会写到磁盘?不是对内存进行操作吗?

数据库sqlite3的使用-基本语法

如何在Linux下用C/C++语言操作数据库sqlite3

如何逐条读出文件中的sql语句并且在sqlite3中批量执行 c、C++都可以

为啥字符串不等于 sqlite3 数据库中的文本值(Python)