SQLite中针对国际字符的upper() alike函数

3

实际上,这个问题已经被问了几次,但我没能找到答案。

有一组SQLite表是只读的 - 我不能改变它们的结构或重新定义排序规则。这些表包含一些国际字符(俄语/中文等)。

我想要进行一些不区分大小写的选择,例如:

select name from names_table where upper(name) glob "*"+constraint.toUpperCase()+"*"

只有当name是拉丁/ ASCII字符集时才有效,对于国际字符则无效。

SQLite的手册中写道:

upper(X)函数返回输入字符串X的副本,在其中所有小写ASCII字符都转换为它们的大写等效项。

因此问题是:如何解决这个问题并使国际字符变成大/小写?

2个回答

6
这是sqlite中的已知问题。你可以通过Android NDK重新定义内置函数。但这并不是一种简单的方法。请查看这个问题
请注意,表的索引将无法使用(对于UDF),查询可能会非常缓慢。
相反,你可以将你要查找的数据以ascii格式存储在其他列中。
例如:
"insert into names_table (name, name_ind) values ('"+name+"',"+"'"+toAsciiEquivalent(name)+"')"

name    name_ind
----------------
Имя     imya
Name    name
ыыы     yyy

通过列名_ind搜索字符串

select name from names_table where name_ind glob "*"+toAsciiEquivalent(constraint)+"*"

这种解决方案需要更多的数据空间,但它简单快速。


你可以使用另一个拥有所需表格和列的数据库,并将此数据库附加到原始数据库。但在这种情况下,同步过程会更加复杂。 - matreshkin
@matreshkin 你好!你能否更具体地说明一下toAsciiEquivalent()方法的实现?可以提供一些代码示例吗?另外,我是否正确地理解它可以与LIKE语句一起使用? - AlexKost
toAsciiEquivalent() 的实现严格依赖于您使用的语言。实际上,此函数应将单词转换为拉丁字母表。有关俄语的示例可以在此页面上找到(请参见 toTranslit 函数):http://www.sql.ru/forum/502128/russkiy-translit - matreshkin
是的,像语句将适用于那些经过音译的字符串,如预期的那样 - 索引将起作用,搜索将快速。 - matreshkin

1
SQLite不提供完整的Unicode大小写支持,而是提供了链接外部Unicode比较和转换例程的能力。应用程序可以重载内置的NOCASE排序序列(使用sqlite3_create_collation()),以及内置的like()、upper()和lower()函数(使用sqlite3_create_function())。SQLite源代码包括一个名为“ICU”的扩展,它执行这些重载。或者,开发人员可以根据其项目中已包含的自己的Unicode感知比较例程编写自己的重载。
参考:http://www.sqlite.org/faq.html

谢谢回复。但是如何在Java/Android中实现呢?考虑到原始表只是只读的?我真的很感激你的帮助。 - Barmaley
我喜欢做那件事,但我是一名C++程序员,对Java了解较少。 - Vijendra Singh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接