如何在字符串比较时将Sqlite3设置为不区分大小写?

qua*_*ity 282 sqlite case-insensitive

我想通过字符串匹配从sqlite3数据库中选择记录.但是如果我在where子句中使用'=',我发现sqlite3区分大小写.任何人都可以告诉我如何使用字符串比较不区分大小写?

che*_*rdo 466

您可以COLLATE NOCASESELECT查询中使用:

SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE
Run Code Online (Sandbox Code Playgroud)

另外,在SQLite中,您可以通过collate nocase在列定义中指定(其他选项是binary(默认值)和rtrim;请参阅此处)来指示在创建表时列应该不区分大小写.您也可以指定collate nocase何时创建索引.例如:

create table Test
(
  Text_Value  text collate nocase
);

insert into Test values ('A');
insert into Test values ('b');
insert into Test values ('C');

create index Test_Text_Value_Index
  on Test (Text_Value collate nocase);

涉及的表达式Test.Text_Value现在应该不区分大小写.例如:

sqlite> select Text_Value from Test where Text_Value = 'B';
Text_Value      
----------------
b               

sqlite> select Text_Value from Test order by Text_Value;
Text_Value      
----------------
A               
b               
C    

sqlite> select Text_Value from Test order by Text_Value desc;
Text_Value      
----------------
C               
b               
A               

优化器还可以利用索引对列进行不区分大小写的搜索和匹配.您可以使用explainSQL命令检查这一点,例如:

sqlite> explain select Text_Value from Test where Text_Value = 'b';
addr              opcode          p1          p2          p3                               
----------------  --------------  ----------  ----------  ---------------------------------
0                 Goto            0           16                                           
1                 Integer         0           0                                            
2                 OpenRead        1           3           keyinfo(1,NOCASE)                
3                 SetNumColumns   1           2                                            
4                 String8         0           0           b                                
5                 IsNull          -1          14                                           
6                 MakeRecord      1           0           a                                
7                 MemStore        0           0                                            
8                 MoveGe          1           14                                           
9                 MemLoad         0           0                                            
10                IdxGE           1           14          +                                
11                Column          1           0                                            
12                Callback        1           0                                            
13                Next            1           9                                            
14                Close           1           0                                            
15                Halt            0           0                                            
16                Transaction     0           0                                            
17                VerifyCookie    0           4                                            
18                Goto            0           1                                            
19                Noop            0           0                                            

  • `COLLATE NOCASE`只适用于ASCII文本.一旦您的列值中有"FIANCÉ"或"voilà",它将与"未婚夫"或"VOILA"不匹配.启用ICU扩展后,[`LIKE`变得不区分大小写](http://www.sqlite.org/src/artifact?ci=trunk&filename=ext/icu/README.txt),所以''FIANCÉ'Like' fiancé'`是真的,但''VOILA'喜欢'voilà'`仍然是假的.并且ICU + LIKE有不使用索引的缺点,因此在大表上可能会很慢. (25认同)
  • 在(重新)使用'COLLATE NOCASE'创建表之后,我注意到它比查询WHERE name ='someone'COLLATE NOCASE快了_much_.快得多(大概是6到10倍?) (17认同)
  • 根据文档,如果字段本身已经定义了这种排序规则,则不需要在索引中添加"COLLATE NOCASE":"[*默认排序顺序是在CREATE TABLE语句中为该列定义的排序顺序.*]( http://www.sqlite.org/lang_createindex.html)" (9认同)
  • 需要注意的一件事就是让我失望:`select*from tbl where firstname ='john'和lastname ='doe'COLLATE NOCASE`将对`lastname`不区分大小写.要对`firstname`不区分大小写,请写下:`select*from tbl where firstname ='john'COLLATE NOCASE and lastname ='doe'`.它特定于那一列,而不是整个`where`子句. (4认同)

Cra*_*raz 145

SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE
Run Code Online (Sandbox Code Playgroud)

  • 如果你像我一样想要关于整理的更多文档,你可以在这个页面找到它:http://www.sqlite.org/datatype3.html向下滚动到#6.0 (5认同)
  • @Will https://www.sqlite.org/datatype3.html#collat​​ing_sequences-直接链接 (2认同)

Nic*_*kis 45

你可以这样做:

SELECT * FROM ... WHERE name LIKE 'someone'
Run Code Online (Sandbox Code Playgroud)

(这不是解决办法,但在某些情况下是非常方便)

" LIKE运算符进行模式匹配比较.右边的操作数包含模式,左边的操作数包含与模式匹配的字符串.模式中的百分比符号("%")匹配零或更多的任何序列字符串中的字符.模式中的下划线("_")匹配字符串中的任何单个字符.任何其他字符匹配 自身或其大小写 等效(即不区分大小写的 匹配).(一个错误:SQLite只能理解ASCII字符的大写/小写.LELE运算符对超出ASCII范围的unicode字符区分大小写.例如,表达式'a'LIKE'A'为TRUE,但'æ'LIKE'Æ'为FALSE.) ".


osc*_*kuo 40

这不是sqlite特有的,但你可以这样做

SELECT * FROM ... WHERE UPPER(name) = UPPER('someone')
Run Code Online (Sandbox Code Playgroud)

  • 请注意这一点,正如cheduardo暗示的那样,SQLite在运行此查询时无法使用"name"上的索引.数据库引擎需要全部扫描所有行,将所有"名称"字段转换为大写并运行比较. (13认同)
  • 这样做是否有任何性能损失? (3认同)

小智 6

另一种选择是创建您自己的自定义排序规则。然后,您可以在列上设置该排序规则或将其添加到您的选择子句中。它将用于排序和比较。

\n\n

这可以用来使“VOILA”像“voil\xc3\xa0\”一样。

\n\n

http://www.sqlite.org/capi3ref.html#sqlite3_create_collat​​ion

\n\n
\n

如果第一个字符串小于、等于或大于第二个字符串,则整理函数必须分别返回负整数、零整数或正整数。

\n
\n