Comparaison de chaînes sensibles à la casse SQL

234

Comment comparez-vous les chaînes pour que la comparaison ne soit vraie que si les cas de chacune des chaînes sont également égaux. Par exemple:

Select * from a_table where attribute = 'k'

... renverra une ligne avec un attribut "K". Je ne veux pas de ce comportement.

amccormack
la source
Ce n'est peut-être pas ce dont vous avez besoin, mais vous pouvez modifier le classement ou utiliser un classement spécifique dans votre requête.
Kane
7
Quel produit SQL?
quand

Réponses:

388
Select * from a_table where attribute = 'k' COLLATE Latin1_General_CS_AS 

A fait l'affaire.

amccormack
la source
4
Je normalement utiliser Latin1_General_BIN
gbn
3
Oui, l'approche standard consiste à utiliser un classement insensible à la casse, bien que les classements eux-mêmes soient spécifiques au fournisseur. La syntaxe de SQL Server est-elle la vôtre?
quand
Dans mon cas, j'ai 1 colonne dans ma base de données qui est sensible à la casse. J'avais besoin de le comparer à une colonne standard (CI). J'ai utilisé une variante de ce WHERE Foo.Bar = (Baz.Bar COLLATE Latin1_General_CS_AS)
Hypnovirus
2
Merci mais qu'est-ce que Latin1_General_CS_AS ?? Est-ce un mot-clé spécial?
Vijay Singh Rana
2
@VijaySinghRana Latin1_General_CS_ASest une spécification du classement. Le classement fait référence à un ensemble de règles qui déterminent comment les données sont triées et comparées. Consultez cette page pour plus d'informations.
amccormack
51

Vous pouvez également convertir cet attribut en respectant la casse à l' aide de cette syntaxe:

ALTER TABLE Table1
ALTER COLUMN Column1 VARCHAR(200)
COLLATE SQL_Latin1_General_CP1_CS_AS

Votre recherche sera désormais sensible à la casse .

Si vous souhaitez rendre ce cas de colonne insensible à nouveau, utilisez

ALTER TABLE Table1
ALTER COLUMN Column1 VARCHAR(200)
COLLATE SQL_Latin1_General_CP1_CI_AS
Jugal
la source
29

Vous pouvez facilement convertir des colonnes en VARBINARY (longueur maximale), la longueur doit être le maximum que vous attendez pour éviter une comparaison défectueuse, il suffit de définir la longueur comme longueur de colonne. La colonne Trim vous aide à comparer la valeur réelle, sauf que l'espace a une signification et une valeur dans les colonnes de votre tableau.Ceci est un exemple simple et comme vous pouvez le voir, je coupe la valeur des colonnes, puis convertis et compare:

CONVERT(VARBINARY(250),LTRIM(RTRIM(Column1))) = CONVERT(VARBINARY(250),LTRIM(RTRIM(Column2)))

J'espère que cette aide.

QMaster
la source
2
exactement ce que je cherchais. Un moyen simple d'effectuer une comparaison ponctuelle et sensible à la casse pour trouver les entrées contenant des caractères majuscules.
Mike
20

Tout comme une autre alternative, vous pouvez utiliser HASHBYTES, quelque chose comme ceci:

SELECT * 
FROM a_table 
WHERE HASHBYTES('sha1', attribute) = HASHBYTES('sha1', 'k')
Dave Sexton
la source
1
Et les collisions? Ce serait rare, mais je suppose qu'il y aurait plusieurs chaînes qui hachent à la même valeur.
David Klempfner
Oui, mais extrêmement rare sur un exemple de chaîne aussi simple que j'aurais pensé.
Dave Sexton
@DavidKlempfner pourquoi ne pas d'abord faire la comparaison et s'ils correspondent alors vérifier également les hashbytes? Nous pourrions en faire une fonction et l'invoquer comme StringsAreCaseSensitiveEqual (a, b) => a = b AND HASHBYTES ('sha1', a) = HASHBYTES ('sha1', b)
Demetris Leptos
3

Vous pouvez définir attributecomme BINARYou utiliser INSTRou STRCMPpour effectuer votre recherche.

MatTheCat
la source
Cette réponse ne semble pas concerner SQL Server par la balise de question. Ce SGBD n'a pas ces fonctions INSTRet STRCMP.
Jonas