Als u in SQL Server rijen met kleine letters moet vinden, kunt u een van de volgende opties proberen.
Voorbeeldgegevens
Stel dat we een tabel hebben met de volgende gegevens:
SELECT c1 FROM t1;
Resultaat:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | café | | 1café | | eCafé | | James Bond 007 | | JB 007 | | 007 | | NULL | | | | É | | É 123 | | é | | é 123 | | ø | | Ø | +----------------+
We kunnen de volgende methoden gebruiken om de rijen met kleine letters te retourneren.
Optie 1:Vergelijk met de UPPER()
Tekenreeks
We kunnen de UPPER()
. gebruiken functie om de oorspronkelijke waarde te vergelijken met het equivalent in hoofdletters:
SELECT * FROM t1
WHERE UPPER(c1) COLLATE Latin1_General_CS_AS <> c1;
Resultaat:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | | é | | é 123 | | ø | +----------------+
Door het gebruik van de niet gelijk aan (<>
) operator (u kunt ook !=
in plaats van <>
als je dat liever hebt), retourneren we alleen die rijen die verschillen van hun equivalenten in hoofdletters. De reden dat we dit doen is omdat, als een waarde hetzelfde is als het equivalent in hoofdletters, het in het begin al in hoofdletters was (en we willen het niet teruggeven).
We gebruiken ook COLLATE Latin1_General_CS_AS
om expliciet een hoofdlettergevoelige (en accentgevoelige) sortering op te geven. Zonder dit kunt u onverwachte resultaten krijgen, afhankelijk van de sortering die op uw systeem wordt gebruikt.
Optie 2:Vergelijk met de werkelijke karakters
We kunnen ook de LIKE
. gebruiken operator, en specificeer de eigenlijke kleine letters die we willen matchen:
SELECT * FROM t1
WHERE c1 LIKE '%[abcdefghijklmnopqrstuvwxyz]%'
COLLATE Latin1_General_CS_AS;
Resultaat:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
In dit geval worden er minder rijen geretourneerd dan in het vorige voorbeeld. Dit komt omdat ik geen tekens zoals é
. heb gespecificeerd en ø
, die in het vorige voorbeeld zijn geretourneerd. Hoewel één rij wel é
. bevat , die rij is alleen geretourneerd omdat deze ook andere kleine letters bevat die wel overeenkomen.
Daarom is dit voorbeeld beperkter dan het vorige, maar het geeft je wel meer controle over de karakters die je wilt matchen.
Optie 3:vergelijken met een reeks tekens
We kunnen ook het bereik van tekens specificeren dat we willen matchen:
SELECT * FROM t1
WHERE c1 LIKE '%[a-z]%'
COLLATE Latin1_General_100_BIN2;
Resultaat:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
In dit geval heb ik een binaire sortering gebruikt (Latin1_General_100_BIN2
). Ik deed dit omdat binaire sorteringen elk geval apart sorteren (zoals dit:AB....YZ...ab...yz
).
Andere sorteringen hebben de neiging om hoofdletters en kleine letters te vermengen (zoals deze:AaBb...YyZz
), wat dus overeen zou komen met zowel hoofdletters als kleine letters.
Optie 4:Zoek de eerste instantie van een kleine letter
Een andere manier om dit te doen is door de PATINDEX()
. te gebruiken functie:
SELECT * FROM t1
WHERE PATINDEX('%[abcdefghijklmnopqrstuvwxyz]%', c1
COLLATE Latin1_General_CS_AS) > 0;
Resultaat:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
In dit voorbeeld specificeren we de exacte tekens die we willen matchen, en dus hebben we in dit geval geen rijen gekregen met tekens zoals é
en ø
(anders dan degene die ook andere tekens bevat die overeenkomen).
Een voordeel van deze techniek is dat we deze kunnen gebruiken om het eerste teken (of het opgegeven aantal tekens) te negeren als we dat willen:
SELECT * FROM t1
WHERE PATINDEX('%[abcdefghijklmnopqrstuvwxyz]%', c1
COLLATE Latin1_General_CS_AS) > 1;
Resultaat:
+----------------+ | c1 | |----------------| | Café | | 1café | | James Bond 007 | +----------------+
Daarom kunnen we alle rijen retourneren die kleine letters bevatten, maar waarvan het eerste teken geen kleine letters is.
Dit komt omdat PATINDEX()
retourneert de startpositie van het eerste voorkomen van het patroon (in ons geval is het patroon een lijst met kleine letters). Als de startpositie van de eerste instantie groter is dan 1, dan staat het eerste teken niet in onze lijst met kleine letters.
Hoewel deze techniek kan worden gebruikt om het eerste teken als hoofdletter te negeren, sluit het niet uit dat het eerste teken een ander teken kan zijn, zoals een cijfer. We kunnen dit zien in de tweede rij, die 1café
. bevat .
Optie 5:vind het eerste exemplaar op basis van een bereik
We kunnen ook PATINDEX()
. gebruiken met een bereik:
SELECT * FROM t1
WHERE PATINDEX('%[a-z]%', c1
COLLATE Latin1_General_100_BIN2) > 1;
Resultaat:
+----------------+ | c1 | |----------------| | Café | | 1café | | James Bond 007 | +----------------+
Ik heb opnieuw een binaire sortering gebruikt (zoals bij het andere bereikvoorbeeld).