如何在Android CursorLoader中使用SQL COLLATE运算符

时间:2018-02-07 12:14:07

标签: java android sqlite kotlin collation

我需要创建CursorLoader,它将提取与名称和类型匹配的所有项目。更多名称必须忽略特定于区域设置的字母(重音符号)。例如,如果我提供查询:

item_name LIKE '%cafe%' COLLATE LOCALIZED

然后我需要提取所有项目,其名称包含'cafe'OR'café'。我不知道如何提供COLLATE操作符来构建那样的查询(没有普通的SQL)。

    return CursorLoader(
            context,
            someUri,
            arrayOf(
                    PrompterTable.WORD_C,
                    PrompterTable.WORD_PLAIN_C,
                    PrompterTable.ENTRY_ID_C,
                    PrompterTable.CATEGORY_ID_C,
                    lengthClause,
                    PrompterTable.FAVOURITE_C
            ),
            "item_name LIKE ? COLLATE LOCALIZED AND item_type IN (0, 1)",
            arrayOf(myItemName),
            "L" //alias given to lengthClause before
    )

我确实将数据库语言环境设置为西班牙语,我也尝试了几种方法来构建WHERE语句:

"item_name LIKE ? COLLATE LOCALIZED AND item_type IN (0, 1)"
"(item_name LIKE ? COLLATE LOCALIZED) AND item_type IN (0, 1)"
"item_name LIKE ? AND item_type IN (0, 1) COLLATE LOCALIZED"
"item_name = ? AND item_type IN (0, 1) COLLATE LOCALIZED"
"item_name = ? COLLATE LOCALIZED AND item_type IN (0, 1)"
"(item_name = ? COLLATE LOCALIZED) AND item_type IN (0, 1)"

但他们每个人都不会按需要工作(只找到'咖啡馆')。查询计算如下:

    SELECT word, item_name, entryID, item_type,  length(word) as L , favourite 
    FROM item_table 
    WHERE (item_name LIKE '%cafe%' COLLATE LOCALIZED AND item_type IN (0, 1)) 
    GROUP BY word ORDER BY L LIMIT 25

我尝试引用此主题:Using COLLATE in Android SQLite - Locales is ignored in LIKE statement

但在我的情况下,即使使用'='而不是LIKE

也不会起作用

1 个答案:

答案 0 :(得分:0)

我找到了答案,但这不是我所希望的。方便的COLLATE LOCALIZED在Nougat版本中从Android中移除,不会以任何方式替换。

已知的解决方法是:

  • 在编码中执行过滤(使用Normalizer.normalize或Collat​​or java对象)
  • 使用规范化名称(无重音符号等)向过滤表中添加其他列,并将用户输入与此列进行比较
  • 将自定义COLLATOR添加到SQLite数据库,听起来很酷但没有Java API这样做。您必须使用Anroid NDK并使用C ++代码编写它。

如果您希望得到详细的答案,我会在租用中找到这些: https://discuss.zetetic.net/t/workaround-for-using-androids-localized-collator-after-3-5-0-update/1515/14