【问题标题】:How to use SQL COLLATE operator with Android CursorLoader如何在 Android CursorLoader 中使用 SQL COLLATE 运算符
【发布时间】:2018-07-17 17:27:32
【问题描述】:

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

item_name LIKE '%cafe%' COLLATE LOCALIZED

然后我需要提取名称包含“cafe”或“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,它也不起作用

【问题讨论】:

  • 嘿 Michal,我有一个小建议,您是否考虑过将其移至对象?也许处理您想要考虑的异常或案例会更容易。
  • 如果您的意思是将过滤移到代码中,那么是的。但是有两个问题:遗留代码在这个解决方案中会更有效(我被明确要求使用 SQL 来实现),第二个是 Java Collat​​or 不能很好地处理某些字母(例如波兰语 a 和 ą 不会可以很好地进行比较)所以它会更多的编码来做这件事:/

标签: java android sqlite kotlin collation


【解决方案1】:

我找到了答案,但这不是我所希望的。方便的 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

【讨论】:

    猜你喜欢
    • 2019-08-26
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多