Comment configurer Sqlite3 pour qu'il ne soit pas sensible à la casse lors d'une comparaison de chaîne de caractères?
je veux sélectionner des enregistrements de la base de données sqlite3 par correspondance de chaîne de caractères. Mais si j'utilise " = " dans la clause where, j'ai trouvé que sqlite3 est sensible à la casse. Est-ce que quelqu'un peut me dire comment utiliser une chaîne de caractères pour comparer des cas insensibles?
10 réponses
vous pouvez utiliser COLLATE NOCASE
dans votre SELECT
requête:
SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE
de plus, en SQLite, vous pouvez indiquer qu'une colonne devrait être insensible à la casse lorsque vous créez la table en spécifiant collate nocase
dans la définition de la colonne (les autres options sont binary
(la valeur par défaut) et rtrim
; voir ici ). Vous pouvez spécifier collate nocase
lorsque vous créez un index. Par exemple:
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);
les Expressions impliquant Test.Text_Value
devraient maintenant être insensibles à la casse. Par exemple:
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
l'optimiseur peut aussi utiliser l'index pour la recherche et l'appariement sur la colonne. Vous pouvez vérifier cela en utilisant la commande explain
SQL, par exemple:
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
Vous pouvez le faire comme ceci:
SELECT * FROM ... WHERE name LIKE 'someone'
(ce n'est pas la solution , mais dans certains cas est très pratique)
" COMME opérateur fait un modèle comparaison correspondante. L'opérande de la droite contient le motif, la l'opérande de gauche contient la chaîne pour le match contre le patron. Un symbole du pourcentage ( " % " ) dans le dessin correspond à toute séquence de zéro ou plus caractères dans la chaîne. Un soulignement ( " _ " ) dans le motif correspond à n'importe quel caractère chaîne. tout autre caractère correspond elle-même ou son minuscule/majuscule équivalent (c.-à-d. insensible à la casse matching) . (Un bug: SQLite seulement comprend les majuscules et les minuscules pour les ASCII caractère. L'opérateur LIKE est le cas sensibles pour les caractères unicode sont au-delà de la Gamme ASCII. Pour exemple, l'expression " a "comme " A" est vrai mais 'æ' comme ' Æ ' est faux.)."
ce n'est pas spécifique à sqlite mais vous pouvez juste faire
SELECT * FROM ... WHERE UPPER(name) = UPPER('someone')
une Autre option est de créer votre propre classement. Vous pouvez alors définir cette collation sur la colonne ou l'ajouter à vos clauses select. Il sera utilisé pour la commande et de comparaisons.
cela peut être utilisé pour faire 'VOILA' comme 'voilà'.
http://www.sqlite.org/capi3ref.html#sqlite3_create_collation
la fonction de collationnement doit retourner un entier qui est négatif, zéro, ou positif si la première chaîne est inférieure, égale, ou supérieure à la seconde, respectivement.
une autre option qui peut ou ne peut pas avoir de sens dans votre cas, est d'avoir réellement une colonne séparée avec des valeurs prédéfinies de votre colonne existante. Cela peut être rempli en utilisant la fonction SQLite LOWER()
, et vous pouvez alors effectuer l'appariement sur cette colonne à la place.
évidemment, il ajoute de la redondance et un potentiel d'incohérence, mais si vos données sont statiques, il pourrait être une option appropriée.
si la colonne est de type char
alors vous devez ajouter la valeur que vous posez avec des espaces, s'il vous plaît se référer à cette question ici . Ceci en plus d'utiliser COLLATE NOCASE
ou l'une des autres solutions (upper(), etc).
vous pouvez utiliser la requête like pour comparer la chaîne respective avec les vales de table.
sélectionner le nom de la colonne à partir de table_name où le nom de la colonne comme 'valeur de comparaison respective';
simplement, vous pouvez utiliser COLLATE NOCASE dans votre requête SELECT:
SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE
ça marche parfaitement pour moi.
SELECT NAME FROM TABLE_NAME WHERE NAME = 'test Name' COLLATE NOCASE