【问题标题】:Case sensitive and insensitive like in SQLite区分大小写和不区分大小写,如 SQLite
【发布时间】:2013-03-06 23:53:55
【问题描述】:

在 SQLite 中,可以使用以下命令更改“LIKE”的区分大小写行为:

PRAGMA case_sensitive_like=ON;
PRAGMA case_sensitive_like=OFF;

但是在我的情况下,我想执行一个查询,其中一部分区分大小写,一部分不区分大小写。例如:

SELECT * FROM mytable
WHERE caseSensitiveField like 'test%'
AND caseInsensitiveField like 'g2%'

这可能吗?

【问题讨论】:

标签: sqlite case-sensitive


【解决方案1】:

您可以在不区分大小写的字段上使用 UPPER 关键字,然后将 like 语句大写。例如

SELECT * FROM mytable 
WHERE caseSensitiveField like 'test%' 
AND UPPER(caseInsensitiveField) like 'G2%'

【讨论】:

  • @AlexanderMalakhov 也适用于意大利语和德语字符。只要确保你在其中导入的数据库和数据都是 UTF-8 编码,并且它可以工作。
  • @rbedger 注意,don't need the Upper function,因为 Like 默认情况下不区分大小写。
  • @FrankN.Stein 这是可行的,但不是开箱即用的。来自official FAQThe default configuration of SQLite only supports case-insensitive comparisons of ASCII characters.
  • 我这样做了:因为我计划使用 UTF-8 字符,所以我将表格保存为 UTF-8 CSV 文件。然后从 SQLiteManager(FireFox 插件)中的 CSV 文件生成我的表。然后更改了数据库配置中的某些内容(不记得什么以及是否真的需要)。然后将我的索引添加到 WHERE 和 JOIN 字段。仅此而已。
  • 通过编辑“UPPER()”,您最终得到的代码与问题中 OP 发布的代码相同。如果您想完全更改答案,请这样做,或者如果您想删除答案,请说出来;但是您所做的编辑毫无意义。
【解决方案2】:

使用普通比较,默认情况下区分大小写(除非您已声明列COLLATE NOCASE):

SELECT *
FROM mytable 
WHERE caseSensitiveField >= 'test'
  AND caseSensitiveField <  'tesu'
  AND caseInsensitiveField LIKE 'g2%'

这仅在原始 LIKE 正在搜索前缀时才有效,但允许使用索引。

【讨论】:

    【解决方案3】:

    我知道这是一个老问题,但如果您使用 Java 编码并遇到此问题,这可能会有所帮助。您可以注册一个处理类似检查的函数。我收到了这篇帖子的提示:https://stackoverflow.com/a/29831950/1271573

    我依赖sqlite jdbc的解决方案:https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc

    在我的情况下,我只需要查看某个字符串是否作为另一个字符串的一部分存在(例如 '%mystring%'),所以我创建了一个 Contains 函数,但应该可以扩展它以执行更多 sql - 使用正则表达式或其他东西进行检查。

    要在 SQL 中使用该函数来查看 MyCol 是否包含“搜索字符串”,您可以这样做:

    select * from mytable where Contains(MyCol, 'searchstring')
    

    这是我的 Contains 函数:

    public class Contains extends Function {
    
        @Override
        protected void xFunc() throws SQLException {
            if (args() != 2) {
                throw new SQLException("Contains(t1,t2): Invalid argument count. Requires 2, but found " + args());
            }
            String testValue = value_text(0).toLowerCase();
            String isLike = value_text(1).toLowerCase();
    
            if (testValue.contains(isLike)) {
                result(1);
            } else {
                result(0);
            }
        }
    }
    

    要使用此功能,您必须先注册它。完成使用后,您可以选择销毁它。方法如下:

    public static void registerContainsFunc(Connection con) throws SQLException   {
        Function.create(con, Contains.class.getSimpleName(), new Contains());
    }
    public static void destroyContainsFunc(Connection con) throws SQLException {
        Function.destroy(con, Contains.class.getSimpleName());
    }
    

    【讨论】:

    • 在我的代码中发现了一个错误。如果您使用 Contains 函数的列允许空值,则应在应用 toLowerCase 函数之前检查 value_text(n) 是否为空。
    【解决方案4】:

    在 SQLite 中,您可以使用 GLOB 代替 LIKE 进行模式搜索。例如:

    SELECT * FROM mytable
    WHERE caseSensitiveField GLOB 'test*'
    AND caseInsensitiveField LIKE 'g2%'
    

    通过这种方法,您不必担心 PRAGMA。

    【讨论】:

    • LIKE 'g2%' 默认情况下仅对模式内的 ascii 字符不区分大小写。 % 匹配的部分无关紧要,因为它代表任何东西。但是 'g2' 必须是非 unicode 字符以进行不区分大小写的匹配。 'üb%' 将匹配 über 但不匹配 Über 请参阅 sqlite.org/faq.html#q18
    【解决方案5】:

    我使用正则表达式来做我需要的事情。我想找出所有出现的不是全部小写的单词“In”。

    select [COL] from [TABLE] where [COL] REGEXP '\bIn\b';
    

    例子:

    with x as (select 'in' Diff_Ins union select 'In' Diff_Ins)
    select Diff_Ins from x where Diff_Ins REGEXP '\bIn\b';
    

    【讨论】:

    • 提醒其他读者,默认没有正则表达式。 “REGEXP 运算符是 regexp() 用户函数的特殊语法。默认情况下没有定义 regexp() 用户函数,因此使用 REGEXP 运算符通常会导致错误消息。” sqlite.org/lang_expr.html#regexp
    猜你喜欢
    • 2020-02-18
    • 1970-01-01
    • 1970-01-01
    • 2017-10-28
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    相关资源
    最近更新 更多