Je veux une recherche sensible à la casse dans la requête SQL. Mais par défaut, MySQL ne prend pas en compte le cas des chaînes.
Une idée sur la façon de faire une recherche sensible à la casse dans une requête SQL?
la source
Je veux une recherche sensible à la casse dans la requête SQL. Mais par défaut, MySQL ne prend pas en compte le cas des chaînes.
Une idée sur la façon de faire une recherche sensible à la casse dans une requête SQL?
par défaut, MySQL ne considère pas le cas des chaînes
Ce n'est pas tout à fait vrai. Chaque fois que vous create database
dans MySQL, la base de données / schéma a un jeu de caractères et un classement. Chaque jeu de caractères a un classement par défaut; voir ici pour plus d'informations.
Le classement par défaut pour le jeu de caractères latin1
, qui est latin1_swedish_ci
, se trouve être insensible à la casse.
Vous pouvez choisir un classement sensible à la casse, par exemple latin1_general_cs
( grammaire MySQL ):
CREATE SCHEMA IF NOT EXISTS `myschema`
DEFAULT CHARACTER SET latin1
COLLATE latin1_general_cs ;
Cela a un effet sur des choses comme le regroupement et l'égalité. Par exemple,
create table casetable (
id int primary key,
thing varchar(50)
);
select * from casetable;
+----+-------+
| id | thing |
+----+-------+
| 3 | abc |
| 4 | ABC |
| 5 | aBc |
| 6 | abC |
+----+-------+
Dans une base de données sensible à la casse, nous obtenons:
select thing, count(*) from casetable group by thing;
+-------+----------+
| thing | count(*) |
+-------+----------+
| ABC | 1 |
| aBc | 1 |
| abC | 1 |
| abc | 1 |
+-------+----------+
select * from casetable where thing = "abc";
+----+-------+
| id | thing |
+----+-------+
| 3 | abc |
+----+-------+
Dans une base de données insensible à la casse, nous obtenons:
select thing, count(*) from casetable group by thing;
+-------+----------+
| thing | count(*) |
+-------+----------+
| abc | 4 |
+-------+----------+
select * from casetable where thing = "abc";
+----+-------+
| id | thing |
+----+-------+
| 3 | abc |
| 4 | ABC |
| 5 | aBc |
| 6 | abC |
+----+-------+
Notez que vous pouvez également modifier le classement à partir d'une requête . Par exemple, dans la base de données sensible à la casse , je peux faire
select * from casetable where thing collate latin1_swedish_ci = "abc";
+----+-------+
| id | thing |
+----+-------+
| 3 | abc |
| 4 | ABC |
| 5 | aBc |
| 6 | abC |
+----+-------+
Vous devez toujours indiquer avec votre question quelle version de MySQL vous utilisez, car MySQL est en développement constant.
Bon, revenons à votre question:
Les fonctions de chaîne dans MySQL sont toujours sensibles à la casse, vous pouvez donc utiliser toutes les fonctions LOCATE
, POSITION
ou INSTR
.
Par exemple:
SELECT phone FROM user WHERE POSITION('term' IN user_name)>0;
La correspondance de modèle avec l'expression régulière ( RLIKE
ou REGEXP
) est toujours sensible à la casse pour toutes les versions de MySQL, à l'exception de la dernière 3.23.4.
Par exemple:
SELECT phone FROM user WHERE user_name REGEXP 'term';
Pour la comparaison normale (=) et la correspondance de modèle SQL ( LIKE
), le comportement dépend des champs impliqués:
une. CHAR
, VARCHAR
et toutes les variantes des champs TEXT ne comparent pas la casse.
b. CHAR BINARY
, VARCHAR BINARY
Et toutes les variantes de champs BLOB ne se comparent sensible à la casse.
Si vous comparez un champ de (a) avec un champ de (b), la comparaison sera sensible à la casse (la sensibilité à la casse l'emporte). Voir le chapitre "7.2.7 Types de chaînes" du Manuel de référence MySQL et recherchez les instructions sur le tri et les comparaisons.
À partir de la version V3.23.0, il est également possible de forcer une comparaison en respectant la casse avec l'opérateur de transtypage BINARY
, indépendamment des types de champs impliqués. Voir le chapitre "7.3.7 Opérateurs Cast" du Manuel de référence MySQL.
Vous pouvez donc également changer le type de nom_utilisateur, ou avec V3.23.x, essayez quelque chose comme:
SELECT phone FROM user WHERE BINARY username LIKE '%term%';
Dans ma situation, j'utilise Access 2010, mais j'ai eu le même problème mais la solution est différente: utilisez la StrComp()
fonction et testez son retour à zéro.
StrComp( thing, 'abc', 0) = 0
Parce que StrComp()
retourne -1
si le premier argument est "plus petit", 1
s'il est "plus grand" et 0
s'il est "égal", quand StrComp()=0
, vous avez une correspondance sensible à la casse.
Cela fonctionnera dans MySQL quel que soit le jeu de caractères. SÉLECTIONNEZ 'test' REGEXP BINARY 'TEST' COMME RÉSULTAT; Mettre 'BINARY' force une comparaison binaire.
Essayez ceci pour une recherche insensible, cela fonctionne très bien avec de grandes performances:
"SELECT phone FROM user WHERE lower(user_name) like ".srtlower($username);