Nedenfor er fem muligheder for at returnere rækker, der indeholder store bogstaver i SQL Server.
Eksempel på data
Antag, at vi har en tabel med følgende data:
SELECT c1 FROM t1;
Resultat:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | café | | 1café | | eCafé | | James Bond 007 | | JB 007 | | 007 | | NULL | | | | É | | É 123 | | é | | é 123 | | ø | | Ø | +----------------+
Vi kan bruge følgende metoder til at returnere de rækker, der indeholder store bogstaver.
Mulighed 1:Sammenlign med LOWER()
Streng
Vi kan bruge LOWER()
funktion til at sammenligne den oprindelige værdi med dens tilsvarende små bogstaver:
SELECT c1 FROM t1
WHERE LOWER(c1) COLLATE Latin1_General_CS_AS <> c1;
Resultat:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | eCafé | | James Bond 007 | | JB 007 | | É | | É 123 | | Ø | +----------------+
Ved at bruge ikke lig med (<> ) operator (du kan alternativt bruge
!=
i stedet for <> hvis du foretrækker det), returnerer vi kun de rækker, der er forskellige fra deres små bogstaver. Grunden til, at vi gør dette, er, at hvis en værdi er den samme som dens små bogstaver, så var den allerede små bogstaver til at begynde med (og vi ønsker ikke at returnere den).
Vi bruger også COLLATE Latin1_General_CS_AS
for eksplicit at angive en versalfølsom (og accentfølsom) sammenstilling. Uden dette kan du få uventede resultater, afhængigt af den sortering, der bruges på dit system.
Mulighed 2:Sammenlign med de faktiske tegn
En anden mulighed er at bruge LIKE
operator og angiv de faktiske store bogstaver, som vi ønsker at matche:
SELECT c1 FROM t1
WHERE c1 LIKE '%[ABCDEFGHIJKLMNOPQRSTUVWXYZ]%'
COLLATE Latin1_General_CS_AS;
Resultat:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | eCafé | | James Bond 007 | | JB 007 | +----------------+
I dette tilfælde returneres færre rækker end i det foregående eksempel. Dette skyldes, at jeg ikke specificerede tegn som É
og Ø
, som blev returneret i det foregående eksempel. Vores resultat indeholder É
men den række blev kun returneret, fordi den også indeholder andre store bogstaver, der gør match.
Derfor er denne mulighed mere begrænset end den forrige, men den giver dig mere kontrol over de karakterer, du vil matche.
Mulighed 3:Sammenlign med en række tegn
Vi kan alternativt angive rækken af tegn, vi ønsker at matche:
SELECT * FROM t1
WHERE c1 LIKE '%[A-Z]%'
COLLATE Latin1_General_100_BIN2;
Resultat:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | eCafé | | James Bond 007 | | JB 007 | +----------------+
I dette tilfælde brugte jeg en binær sortering (Latin1_General_100_BIN2
). Jeg gjorde dette, fordi binære kollationer sorterer hvert tilfælde separat (som dette:AB...YZ...ab...yz
).
Andre sammenstillinger har en tendens til at blande store og små bogstaver (som dette:AaBb...YyZz
), som derfor ville matche både store og små bogstaver.
Mulighed 4:Find den første forekomst af et stort tegn
En anden måde at gøre det på er at bruge PATINDEX()
funktion:
SELECT * FROM t1
WHERE PATINDEX('%[ABCDEFGHIJKLMNOPQRSTUVWXYZ]%', c1
COLLATE Latin1_General_CS_AS) > 0;
Resultat:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | eCafé | | James Bond 007 | | JB 007 | +----------------+
I dette eksempel specificerer vi de nøjagtige tegn, som vi ønsker at matche, og så i dette tilfælde fik vi ikke rækkerne med tegn som É
og Ø
(andre end den, der også indeholder andre tegn, der blev matchet).
En fordel ved denne teknik er, at vi kan bruge den til at ignorere det første tegn (eller det specificerede antal tegn), hvis vi ønsker det:
SELECT * FROM t1
WHERE PATINDEX('%[ABCDEFGHIJKLMNOPQRSTUVWXYZ]%', c1
COLLATE Latin1_General_CS_AS) > 1;
Resultat:
Time: 0.472s +-------+ | c1 | |-------| | eCafé | +-------+
Derfor kan vi returnere alle rækker, der indeholder store bogstaver, men hvor det første tegn ikke er stort.
Dette er fordi PATINDEX()
returnerer startpositionen for den første forekomst af mønsteret (i vores tilfælde er mønsteret en liste med store bogstaver). Hvis startpositionen for den første forekomst er større end 1, er det første tegn ikke på vores liste over store bogstaver.
Mulighed 5:Find den første instans baseret på et område
Vi kan også bruge PATINDEX()
med et interval:
SELECT * FROM t1
WHERE PATINDEX('%[A-Z]%', c1
COLLATE Latin1_General_100_BIN2) > 1;
Resultat:
+-------+ | c1 | |-------| | eCafé | +-------+
Jeg brugte igen en binær sortering (som med det andet områdeeksempel).