【问题标题】:LIKE case-insensitive for not English lettersLIKE 对非英文字母不区分大小写
【发布时间】:2014-04-16 03:14:03
【问题描述】:

我想检索TITLE 字段符合某种模式(不区分大小写)的行,并且该字段仅包含非英语字母。

我试过了:

SEARCH * FROM TABLE_NAME WHERE UPPER(column_name) LIKE UPPER('%pattern%');

但是,这不起作用,可能是因为表格只包含非英语字母。

更新:

例子:

SELECT * FROM PartnersTable WHERE UPPER(TitleColumn) LIKE UPPER('%pattern%');

地点:

TitleColumn 可能包含“Газпром”、“Лукойл”、“Йотафон”、“Мечта ювелира”

pattern 可能包含“газ”、“Ювелир”等。

【问题讨论】:

  • 你能发布一些你的模式和一些示例数据吗?
  • @LeonidSemyonov 你找到解决方案了吗?

标签: sql sqlite sql-like


【解决方案1】:

我尝试使用添加到列定义的COLLATE NOCASE。如果你能做到,那么这就是要走的路。

我测试了什么:

CREATE TABLE PartnersTable 
    (`id` , `TitleColumn` COLLATE NOCASE )
;

添加了与您的问题相同的数据:

INSERT INTO PartnersTable
    (`id`, `TitleColumn`)
VALUES
 (1, 'Газпром'), (2, 'Лукойл'), (3, 'Йотафон'), (4, 'Мечта ювелира')
;

然后尝试选择它:

select *
from PartnersTable
where TitleColumn like '%Ювелир%'

有效。

这里的演示: http://sqlfiddle.com/#!7/ae8f8/2

编辑: 您也可以在没有UPPER 的情况下使用它。默认情况下,LIKE 不区分大小写。 根据文档:

任何其他字符匹配它自己或它的小写/大写等效(即不区分大小写的匹配)。 (一个错误:SQLite 只理解 ASCII 字符的大写/小写。LIKE 运算符对超出 ASCII 范围的 unicode 字符区分大小写。例如,表达式 'a' LIKE 'A' 为 TRUE 但 'æ' LIKE 'Æ' 是假的。)。”

这里的演示: http://sqlfiddle.com/#!7/c9b5d/1

【讨论】:

  • 很抱歉碰到了相当老的线程,但这确实适用于 sqlfiddle,但不适用于本机 sqlite SQLite 版本 3.27.2 2019-02-25 16:06:06 连接到瞬态 in-内存数据库。使用“.open FILENAME”在持久数据库上重新打开。 sqlite> 创建表 PartnersTable (id , TitleColumn COLLATE NOCASE ); sqlite> INSERT INTO PartnersTable (id, TitleColumn) VALUES (1, 'Газпром'), (2, 'Лукойл'), (3, 'Йогафон'), (4, 'Мечта ювелира'); sqlite> select * from PartnersTable where TitleColumn like '%Га%'; 1|Газпром sqlite>
  • COLLATE NOCASE 仅适用于 ASCII 字符
【解决方案2】:

代码不起作用,因为 UPPER 仅适用于 ASCII 字符 (link)。为了解决这个问题,我使用 .NET 的 BindFunction 实现了用户定义函数,如下所示。

// for System.Data.SQLite
connection.BindFunction(
    new SQLiteFunctionAttribute("myupper", 1, FunctionType.Scalar),
    (Func<object[], object>)((object[] args) => ((string)((object[])args[1])[0]).ToUpper()),
    null);
        
// for Microsoft.Data.Sqlite
connection.CreateFunction(
    "myupper",
    (string arg) => (arg).ToUpper());

var command = connection.CreateCommand();
command.CommandText =
@"
    SELECT *
    FROM PartnersTable 
    WHERE MYUPPER(TitleColumn) LIKE MYUPPER('%pattern%')
";
      
command.ExecuteQuery()

但是执行查询需要更长的时间。

以下链接也可能有帮助

https://docs.microsoft.com/en-us/dotnet/standard/data/sqlite/user-defined-functions https://docs.microsoft.com/en-us/dotnet/standard/data/sqlite/compare

【讨论】:

  • 非常感谢。它帮助了我很多。我使用了 Javascript 自定义函数。
【解决方案3】:

Redifine Like 函数(这使用 Sqlite .NET 包装器)。另请注意 VB 喜欢使用星号通配符。如果您想 % 替换字符串或重新定义 GLOB。

     public static void OverrideLikeFunction()
 {
    SQLiteSpace.SQLiteFunction.RegisterFunction(typeof(SQLiteHelper.Ulike));

}

[System.Data.SQLite.SQLiteFunction(FuncType=System.Data.SQLite.FunctionType.Scalar, Name="Like")]
;
        Public Class Ulike;
            Inherits System.Data.SQLite.SQLiteFunction;
            Public Overrides Function Invoke(args() As object) As object;
            try
            {
                    if (System.Convert.IsDBNull(args(0)) || System.Convert.IsDBNull(args(1)))
                    {
                        return false;
                    }
                    return (Microsoft.VisualBasic.CompilerServices.StringType.StrLike(System.Convert.ToString(args(1)).ToUpperInvariant(), System.Convert.ToString(args(0)).ToUpperInvariant(), Microsoft.VisualBasic.CompareMethod.Binary));
                }
                catch (Exception ex)
                {
                                   return null;
                }
            }

        }

【讨论】:

    【解决方案4】:

    如果您的数据仅包含一组有限的国际字母,一个快速简单的解决方案是使用replace() 手动更改国际字母的大小写。

    例如,就我而言,我只期望 [a-z]、[A-Z] 和 [åäöÅÄÖ]:

    // First, use application code to make the search string lowercase.
    searchStr = searchStr.toLower(); 
    
    // The SQLite function lower() will not affect ÅÄÖ, so we need 
    // to manually replace them with their lowercase versions.
    sql = "SELECT * "+
      " FROM table1 "+
      " WHERE "+
      "   replace(replace(replace( lower(name) , 'Å','å'), 'Ä','ä'), 'Ö','ö') LIKE ?";
    
    db.prepare(sql, ["%"+searchStr+"%"]);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-22
      • 2016-09-05
      • 1970-01-01
      • 2014-08-19
      • 1970-01-01
      • 1970-01-01
      • 2020-02-18
      相关资源
      最近更新 更多