Сравнение строк с учетом регистра SQL

234

Как вы сравниваете строки так, чтобы сравнение было верным, только если случаи каждой из строк одинаковы. Например:

Select * from a_table where attribute = 'k'

... вернет строку с атрибутом 'K'. Я не хочу такого поведения.

amccormack
источник
Это может быть не то, что вам нужно, но вы можете изменить параметры сортировки или использовать конкретные параметры сортировки в своем запросе.
Кейн
7
Какой продукт SQL?
onedaywhen

Ответы:

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

Сделал трюк.

amccormack
источник
4
Я бы обычно использовал Latin1_General_Bin
gbn 19.10.10
3
Да, стандартный подход заключается в использовании сортировки без учета регистра, хотя сами сопоставления зависят от поставщика. Ваш синтаксис SQL Server?
onedaywhen
В моем случае у меня есть 1 столбец в моей базе данных, который чувствителен к регистру. Мне нужно было сравнить его со стандартным (CI) столбцом. Я использовал вариант этого ГДЕ Foo.Bar = (Baz.Bar COLLATE Latin1_General_CS_AS)
Гипновирус
2
Спасибо, но что такое Latin1_General_CS_AS ?? Это специальное ключевое слово?
Виджай Сингх Рана
2
@VijaySinghRana Latin1_General_CS_AS- это спецификация сопоставления. Сличение относится к набору правил, которые определяют, как данные сортируются и сравниваются. Смотрите эту страницу для получения дополнительной информации.
amccormack
51

Вы также можете преобразовать этот атрибут с учетом регистра, используя этот синтаксис:

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

Теперь ваш поиск будет чувствителен к регистру .

Если вы хотите сделать этот столбец снова нечувствительным к регистру , используйте

ALTER TABLE Table1
ALTER COLUMN Column1 VARCHAR(200)
COLLATE SQL_Latin1_General_CP1_CI_AS
скуловой
источник
29

Вы можете легко конвертировать столбцы в VARBINARY (максимальная длина), длина должна быть максимальной, которую вы ожидаете, чтобы избежать дефектного сравнения, достаточно установить длину в качестве длины столбца. Обрезать столбец поможет вам сравнить реальное значение, за исключением того, что пространство имеет значение и значение в столбцах таблицы. Это простой пример, и, как вы можете видеть, я обрезаю значение столбцов, а затем преобразую и сравниваю .:

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

Надеюсь, это поможет.

Qmaster
источник
2
именно то, что я искал. Простой способ выполнить однократное, чувствительное к регистру сравнение, чтобы найти записи, содержащие символы в верхнем регистре.
Майк Д.
20

В качестве другой альтернативы вы можете использовать HASHBYTES, что-то вроде этого:

SELECT * 
FROM a_table 
WHERE HASHBYTES('sha1', attribute) = HASHBYTES('sha1', 'k')
Дейв Секстон
источник
1
А как насчет столкновений? Это было бы редко, но я предполагаю, что будет несколько строк, хэширующих одно и то же значение.
Дэвид Клемпфнер
Да, возможно, но крайне редко на таком простом примере строки, я бы подумал.
Дейв Секстон
@DavidKlempfner, почему бы сначала не выполнить сравнение, а если они совпадают, то также проверить хеш-байты? Мы могли бы сделать это функцией и вызывать ее как StringsAreCaseSensitiveEqual (a, b) => a = b AND HASHBYTES ('sha1', a) = HASHBYTES ('sha1', b)
Деметрис
3

Вы можете определить attributeкак BINARYили использовать INSTRили STRCMPдля выполнения поиска.

MatTheCat
источник
Этот ответ, похоже, не относится к SQL Server для каждого тега вопроса. Та СУБД не хватает этих INSTRи STRCMPфункций.
Джонас