Ако трябва да намерите редове, които съдържат малки букви в SQL Server, можете да опитате една от следните опции.
Примерни данни
Да предположим, че имаме таблица със следните данни:
SELECT c1 FROM t1;
Резултат:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | café | | 1café | | eCafé | | James Bond 007 | | JB 007 | | 007 | | NULL | | | | É | | É 123 | | é | | é 123 | | ø | | Ø | +----------------+
Можем да използваме следните методи, за да върнем редовете, които съдържат малки букви.
Опция 1:Сравнете с UPPER()
Низ
Можем да използваме UPPER()
функция за сравняване на оригиналната стойност с нейния еквивалент с главни букви:
SELECT * FROM t1
WHERE UPPER(c1) COLLATE Latin1_General_CS_AS <> c1;
Резултат:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | | é | | é 123 | | ø | +----------------+
Чрез използване на не е равно на (<>
) оператор (можете да използвате алтернативно !=
вместо <>
ако предпочитате), ние връщаме само онези редове, които са различни от техните еквиваленти с главни букви. Причината да правим това е, че ако стойността е същата като нейния еквивалент с главни букви, тогава тя вече е била с главни букви (и не искаме да я връщаме).
Ние също така използваме COLLATE Latin1_General_CS_AS
за изрично уточняване на съпоставяне, чувствително към малки и големи букви (и акценти). Без това бихте могли да получите неочаквани резултати в зависимост от съпоставянето, което се използва във вашата система.
Вариант 2:Сравнете с действителните знаци
Като алтернатива можем да използваме LIKE
оператор и посочете действителните малки букви, които искаме да съпоставим:
SELECT * FROM t1
WHERE c1 LIKE '%[abcdefghijklmnopqrstuvwxyz]%'
COLLATE Latin1_General_CS_AS;
Резултат:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
В този случай се връщат по-малко редове, отколкото в предишния пример. Това е така, защото не посочих знаци като é
и ø
, които бяха върнати в предишния пример. Въпреки че един ред съдържа é
, този ред беше върнат само защото съдържа и други малки букви, които съвпадат.
Следователно този пример е по-ограничен от предишния, но ви предоставя повече контрол върху знаците, които искате да съпоставите.
Опция 3:Сравнете с набор от знаци
Алтернативно можем да посочим диапазона от знаци, които искаме да съпоставим:
SELECT * FROM t1
WHERE c1 LIKE '%[a-z]%'
COLLATE Latin1_General_100_BIN2;
Резултат:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
В този случай използвах двоично съпоставяне (Latin1_General_100_BIN2
). Направих това, защото двоичните съпоставяния сортират всеки случай поотделно (като това:AB....YZ...ab...yz
).
Други съпоставяния са склонни да смесват главни и малки букви (като това:AaBb...YyZz
), което следователно ще съответства както на главни, така и на малки букви.
Опция 4:Намерете първия екземпляр на малък буквен знак
Друг начин да го направите е да използвате PATINDEX()
функция:
SELECT * FROM t1
WHERE PATINDEX('%[abcdefghijklmnopqrstuvwxyz]%', c1
COLLATE Latin1_General_CS_AS) > 0;
Резултат:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
В този пример ние указваме точните знаци, които искаме да съпоставим, и така в този случай не получихме редовете с знаци като é
и ø
(освен този, който съдържа и други знаци, които са били съвпадащи).
Едно предимство на тази техника е, че можем да я използваме, за да игнорираме първия знак (или определен брой знаци), ако желаем:
SELECT * FROM t1
WHERE PATINDEX('%[abcdefghijklmnopqrstuvwxyz]%', c1
COLLATE Latin1_General_CS_AS) > 1;
Резултат:
+----------------+ | c1 | |----------------| | Café | | 1café | | James Bond 007 | +----------------+
Следователно можем да върнем всички редове, които съдържат малки букви, но където първият символ не е малък.
Това е така, защото PATINDEX()
връща началната позиция на първото появяване на шаблона (в нашия случай шаблонът е списък с малки букви). Ако началната позиция на първото появяване е по-голяма от 1, тогава първият знак не е в нашия списък с малки букви.
Въпреки че тази техника може да се използва за игнориране на първия знак с главни букви, не изключва първият знак да бъде друг знак, като например число. Можем да видим това във втория ред, който съдържа 1café
.
Опция 5:Намерете първия екземпляр въз основа на диапазон
Можем също да използваме PATINDEX()
с диапазон:
SELECT * FROM t1
WHERE PATINDEX('%[a-z]%', c1
COLLATE Latin1_General_100_BIN2) > 1;
Резултат:
+----------------+ | c1 | |----------------| | Café | | 1café | | James Bond 007 | +----------------+
Отново използвах двоично съпоставяне (както с другия пример за диапазон).