web-dev-qa-db-fra.com

Comment puis-je effectuer une recherche sensible à la casse en utilisant LIKE?

J'essaie de trouver des enregistrements contenant une chaîne de 6 caractères alphanumériques ou plus en majuscule. Quelques exemples:

PENDING  3RDPARTY  CODE27

J'utilise la déclaration suivante:

SELECT Details
FROM MyTable
WHERE Details LIKE '%[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]%';

Cela renvoie tous les enregistrements contenant un mot de 6 lettres ou plus, quel que soit le cas.

J'ai ajouté une déclaration COLLATE:

SELECT Details
FROM MyTable
WHERE Details COLLATE Latin1_General_CS_AS LIKE '%[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]%';

Cela ne change rien. Il renvoie toujours des enregistrements avec un mot de 6 lettres ou plus, quel que soit le cas.

Juste comme test, j'ai essayé:

SELECT Details
FROM MyTable
WHERE Details COLLATE Latin1_General_CS_AS LIKE '%pending%';

SELECT Details
FROM MyTable
WHERE Details COLLATE Latin1_General_CS_AS LIKE '%PENDING%';

Ces deux éléments ont fonctionné, renvoyant des enregistrements contenant respectivement "en attente" et "PENDING". Donc, le problème semble résulter de la correspondance de modèle de LIKE claus.

Que puis-je faire pour effectuer cette recherche sensible à la casse?

29
Hand-E-Food

Essayez d'utiliser COLLATE Latin1_General_BIN plutôt que COLLATE Latin1_General_CS_AS 

43
TravellingGeek

Mise à jour due à @GeraldSv: Utiliser le classement Latin1_General_BIN 

SELECT Details
FROM MyTable
WHERE Details 
LIKE '%[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]%' 
COLLATE Latin1_General_BIN;

Vous devez placer le spécificateur de classement after la chaîne à rechercher, plutôt que la colonne:

SELECT Details
FROM MyTable
WHERE Details 
LIKE '%[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]%' 
COLLATE Latin1_General_CS_AS;

Mise à jour: Bien que ma réponse ci-dessus soit correcte, Connect a enregistré un bogue: Case-SENSITIVITY ne fonctionne pas lorsque vous utilisez une plage similaire à COLLATE Latin1_General_CS_AS que Microsoft a marqué "Par conception".

J'ai vérifié en utilisant AdventureWorks2008R2 (insensible à la casse, valeur par défaut), dans la table Person.Person, j'ai changé 3 noms de famille se terminant par 'n' en 'N', puis j'ai exécuté les requêtes suivantes:

SELECT COUNT(*)
FROM Person.Person
WHERE LastName LIKE '%N' COLLATE Latin1_General_CS_AS

Succès. Retourne 3 lignes comme prévu.

SELECT COUNT(*)
FROM Person.Person
WHERE LastName LIKE '%[N]' COLLATE Latin1_General_CS_AS

Succès. Retourne 3 lignes comme prévu.

SELECT COUNT(*)
FROM Person.Person
WHERE LastName LIKE '%[N-N]' COLLATE Latin1_General_CS_AS

Succès. Retourne 3 lignes comme prévu.

SELECT COUNT(*)
FROM Person.Person
WHERE LastName LIKE '%[M-N]' COLLATE Latin1_General_CS_AS

Échoue. Retourne 3334 lignes (ce qui correspond à tous les noms de famille se terminant par 'n' et 'N')

Mise à jour: Grâce à @GeraldSv, cela fonctionne:

SELECT COUNT(*)
FROM Person.Person
WHERE LastName LIKE '%[M-N]' COLLATE Latin1_General_BIN
27
Mitch Wheat

J'utilise les éléments suivants:

SELECT COUNT(*)
FROM Person.Person
WHERE LastName COLLATE Latin1_General_CS_AS != upper(LastName) COLLATE Latin1_General_CS_AS
0
Svensken