Как установить Sqlite3 без учета регистра при сравнении строк? - PullRequest
268 голосов
/ 10 июня 2009

Я хочу выбрать записи из базы данных sqlite3 путем сопоставления строк. Но если я использую '=' в предложении where, я обнаружу, что sqlite3 чувствителен к регистру. Может кто-нибудь сказать мне, как использовать сравнение строк без учета регистра?

Ответы [ 10 ]

444 голосов
/ 10 июня 2009

Вы можете использовать COLLATE NOCASE в своем запросе SELECT:

SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE

Кроме того, в 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               

Оптимизатор также может использовать индекс для поиска и сопоставления без учета регистра в столбце. Вы можете проверить это с помощью команды explain SQL, например ::1010 *

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                                            
144 голосов
/ 10 июня 2009
SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE
43 голосов
/ 10 июня 2009

Вы можете сделать это так:

SELECT * FROM ... WHERE name LIKE 'someone'

(Это не решение, но в некоторых случаях очень удобно)

"Оператор LIKE создает шаблон сопоставление сравнения. Операнд для право содержит образец, левый операнд содержит строку чтобы соответствовать шаблону. символ процента ("%") в шаблоне соответствует любой последовательности от нуля или более символы в строке. подчеркивание ("_") в шаблоне соответствует любому отдельному символу в строка. Соответствует любому другому символу сам или его нижний / верхний регистр эквивалент (т.е. без учета регистра соответствие) . (Ошибка: только SQLite понимает верхний / нижний регистр для ASCII персонажи. Оператор LIKE - это случай чувствителен к символам юникода, которые находятся за пределами диапазона ASCII. За Например, выражение 'a' LIKE 'A' TRUE, но 'æ' LIKE 'Æ' - FALSE.). "

39 голосов
/ 10 июня 2009

Это не относится к sqlite, но вы можете просто сделать

SELECT * FROM ... WHERE UPPER(name) = UPPER('someone')
4 голосов
/ 21 октября 2014

Другой вариант - создать свой собственный порядок сортировки. Затем вы можете установить это сопоставление в столбце или добавить его к выбранным предложениям. Будет использоваться для упорядочивания и сравнения.

Это можно использовать, чтобы сделать 'VOILA' LIKE 'voilà'.

http://www.sqlite.org/capi3ref.html#sqlite3_create_collation

Функция сортировки должна возвращать целое число, которое является отрицательным, нулевым или положительным, если первая строка меньше, равна или больше второй, соответственно.

2 голосов
/ 23 апреля 2017

Другой вариант, который может иметь или не иметь смысла в вашем случае, - это фактически иметь отдельный столбец с предварительно заниженными значениями существующего столбца. Это можно заполнить с помощью функции SQLite LOWER(), и вы можете вместо этого выполнить сопоставление для этого столбца.

Очевидно, что это добавляет избыточность и возможность несогласованности, но если ваши данные статичны, это может быть подходящим вариантом.

1 голос
/ 27 сентября 2018

Проще говоря, вы можете использовать COLLATE NOCASE в вашем запросе SELECT:

SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE
1 голос
/ 29 июня 2017

Вы можете использовать аналогичный запрос для сравнения соответствующей строки с табличными значениями.

выбрать имя столбца из table_name, где имя столбца, например, «соответствующее значение сравнения»;

1 голос
/ 01 мая 2013

Если столбец имеет тип char, то вам нужно добавить значение, которое вы запрашиваете, с пробелами, пожалуйста, обратитесь к этому вопросу здесь . Это в дополнение к использованию COLLATE NOCASE или одного из других решений (upper () и т. Д.).

0 голосов
/ 20 сентября 2017

Это работает для меня отлично. SELECT NAME FROM TABLE_NAME WHERE NAME = 'test Name' COLLATE NOCASE

...