在Android SQLite中使用COLLATE - 在LIKE语句中忽略Locales

时间:2021-02-13 00:46:29

When creating my SQLite database in Android I set the database locale - db.setLocale(new Locale("cz_CZ")). This is a Czech locale.

在Android中创建SQLite数据库时,我设置了数据库语言环境 - db.setLocale(new Locale(“cz_CZ”))。这是一个捷克语的地方。

A SELECT statement works and takes the locale into account, for example:

SELECT语句起作用并考虑区域设置,例如:

SELECT * from table WHERE name='sctzy' COLLATE LOCALIZED 

Will find the entry 'ščťžý'.

会找到条目'ščťžý'。

But using LIKE will fail:

但使用LIKE将失败:

SELECT * from table WHERE name LIKE '%sctzy%' COLLATE LOCALIZED 

No row is returned.

没有返回行。

BTW. There is no java.text.Normalized class in Android. I thought I could make a second column with a normalized text, stripped of special characters, which would be used for searching - but I am missing a class or way how to normalize the String.

BTW。 Android中没有java.text.Normalized类。我以为我可以用标准化的文本制作第二列,删除特殊字符,这些字符将用于搜索 - 但我缺少一个类或方法如何规范化String。

3 个解决方案

#1


7  

Have you had a look at the SQLite documentation for LIKE? It has come information about non ASCII characters and a bug. Maybe Android has an older version of SQLite installed where this is a problem.

您是否看过LIKE的SQLite文档?它提供了有关非ASCII字符和错误的信息。也许Android安装了旧版本的SQLite,这是一个问题。

I think the second normalised column might be your best option unfortunately.

我认为不幸的是,第二个标准化列可能是您最好的选择。

#2


2  

Creating a second normalised column can be used to go around limitations (as mentioned briefly in other answers).

创建第二个规范化列可用于解决限制(在其他答案中简要提及)。

This means in practice that you have to create another (shadow) column of your first where the same data in a fixed case (e.g. all upper chars) is stored. Case insensitive queries (including like queries) can be made on this new column with search values in the same case.

这意味着在实践中你必须创建第一列的另一个(阴影)列,其中存储了固定情况下的相同数据(例如所有上面的字符)。可以在具有相同大小写的搜索值的新列上进行不区分大小写的查询(包括类似查询)。

If the first column "a" contains

AAA
aaa
Bbb
äää
ééé

The second column a_shadow would contain for the same rows

AAA
AAA
BBB
ÄÄÄ
ÉÉÉ

如果第一列“a”包含AAA aaaBbbäääééé第二列a_shadow将包含相同的行AAA AAABBBÄÄÄÉÉÉ

and your original query (example) "select a from mytable where a='äää'"
would be replaced with "select a from mytable where A='ÄÄÄ'"

和你的原始查询(例子)“从mytable中选择一个a ='äää'”将被替换为“从mytable中选择一个A ='ÄÄÄ''”

Your code needs to be updated to fill the converted shadow content when adding the primary content. If the column is added after creation or you cannot change the code existing values may need to be converted using an update query. Example:

添加主要内容时,需要更新代码以填充转换后的阴影内容。如果在创建后添加列,或者您无法更改代码,则可能需要使用更新查询转换现有值。例:

UPDATE mytable SET a_shadow=UPPER(a);

UPDATE mytable SET a_shadow = UPPER(a);

#3


0  

Might be time consuming, but you can use the java.text.Normalizer like here

可能很耗时,但你可以像这里一样使用java.text.Normalizer

Converting Symbols, Accent Letters to English Alphabet

将符号,重音符号转换为英文字母

As is not part of the java subset that Android, you may try to look for it at the code of java, such as Normalizer.java With the Javadoc found here:

由于不是Android的java子集的一部分,您可以尝试在java的代码中查找它,例如Normalizer.java使用此处的Javadoc:

And copy the part of the code needed inside your project.

并复制项目中所需的部分代码。

Hope it works!

希望它有效!

#1


7  

Have you had a look at the SQLite documentation for LIKE? It has come information about non ASCII characters and a bug. Maybe Android has an older version of SQLite installed where this is a problem.

您是否看过LIKE的SQLite文档?它提供了有关非ASCII字符和错误的信息。也许Android安装了旧版本的SQLite,这是一个问题。

I think the second normalised column might be your best option unfortunately.

我认为不幸的是,第二个标准化列可能是您最好的选择。

#2


2  

Creating a second normalised column can be used to go around limitations (as mentioned briefly in other answers).

创建第二个规范化列可用于解决限制(在其他答案中简要提及)。

This means in practice that you have to create another (shadow) column of your first where the same data in a fixed case (e.g. all upper chars) is stored. Case insensitive queries (including like queries) can be made on this new column with search values in the same case.

这意味着在实践中你必须创建第一列的另一个(阴影)列,其中存储了固定情况下的相同数据(例如所有上面的字符)。可以在具有相同大小写的搜索值的新列上进行不区分大小写的查询(包括类似查询)。

If the first column "a" contains

AAA
aaa
Bbb
äää
ééé

The second column a_shadow would contain for the same rows

AAA
AAA
BBB
ÄÄÄ
ÉÉÉ

如果第一列“a”包含AAA aaaBbbäääééé第二列a_shadow将包含相同的行AAA AAABBBÄÄÄÉÉÉ

and your original query (example) "select a from mytable where a='äää'"
would be replaced with "select a from mytable where A='ÄÄÄ'"

和你的原始查询(例子)“从mytable中选择一个a ='äää'”将被替换为“从mytable中选择一个A ='ÄÄÄ''”

Your code needs to be updated to fill the converted shadow content when adding the primary content. If the column is added after creation or you cannot change the code existing values may need to be converted using an update query. Example:

添加主要内容时,需要更新代码以填充转换后的阴影内容。如果在创建后添加列,或者您无法更改代码,则可能需要使用更新查询转换现有值。例:

UPDATE mytable SET a_shadow=UPPER(a);

UPDATE mytable SET a_shadow = UPPER(a);

#3


0  

Might be time consuming, but you can use the java.text.Normalizer like here

可能很耗时,但你可以像这里一样使用java.text.Normalizer

Converting Symbols, Accent Letters to English Alphabet

将符号,重音符号转换为英文字母

As is not part of the java subset that Android, you may try to look for it at the code of java, such as Normalizer.java With the Javadoc found here:

由于不是Android的java子集的一部分,您可以尝试在java的代码中查找它,例如Normalizer.java使用此处的Javadoc:

And copy the part of the code needed inside your project.

并复制项目中所需的部分代码。

Hope it works!

希望它有效!