如何使用指定的语言环境对 sqlite3 中的文本进行排序?
Posted
技术标签:
【中文标题】如何使用指定的语言环境对 sqlite3 中的文本进行排序?【英文标题】:How to sort text in sqlite3 with specified locale? 【发布时间】:2010-10-11 07:40:49 【问题描述】:默认情况下,Sqlite3 仅按 ascii 字母排序。我试图在谷歌中查找,但我发现的唯一内容是有关排序规则的信息。 Sqlite3 只有NOCASE
、RTRIM
和BIARY
排序规则。如何添加对特定语言环境的支持?
(我在 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_collation('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 ,打开指定数据库,执行插入操作后会啥会写到磁盘?不是对内存进行操作吗?