Порівняйте рядки, що чутливі до регістру SQL


234

Як ви порівнюєте рядки, щоб порівняння було істинним, лише якщо випадки кожної з рядків також рівні. Наприклад:

Select * from a_table where attribute = 'k'

... поверне рядок з атрибутом "K". Я не хочу такої поведінки.


Це може бути не те, що вам потрібно, але ви можете змінити Collation або використати певний Collation у вашому запиті.
Кейн

7
Який продукт SQL?
день, коли

Відповіді:


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

Зробив трюк.


4
Я зазвичай використовую Latin1_General_Bin
gbn

3
Так, стандартний підхід полягає у використанні порівняльного врахування регістру, хоча самі посилання залежать від постачальника. Ваш синтаксис SQL Server?
день, коли

У моєму випадку в моєму db є 1 стовпець, що залежить від регістру. Мені потрібно було порівняти його зі стандартним (CI) стовпцем. Я використав варіацію цього WHERE Foo.Bar = (Baz.Bar COLLATE Latin1_General_CS_AS)
Hypnovirus

2
Дякую, але що таке Latin1_General_CS_AS ?? Це спеціальне ключове слово?
Vijay Singh Rana

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)))

Сподіваюся, що це допоможе.


2
саме те, що я шукав. Простий спосіб зробити одноразове порівняння з великим регістром, щоб знайти записи, що містять великі регістри.
Майк Д.

20

Як ще одну альтернативу ви можете використовувати HASHBYTES, приблизно так:

SELECT * 
FROM a_table 
WHERE HASHBYTES('sha1', attribute) = HASHBYTES('sha1', 'k')

1
А як зіткнення? Це було б рідко, але я припускаю, що було б кілька рядків, що мають однакове значення.
Девід Клемпфнер

Так, можливо, але вкрай рідко на такому простому рядковому прикладі я міг би подумати.
Дейв Секстон

@DavidKlempfner чому б спочатку не порівняти, а якщо вони відповідають, то також перевірити наявність хешбайтів? Ми могли б зробити цю функцію і викликати її як StringsAreCaseSensitiveEqual (a, b) => a = b І HASHBYTES ('sha1', a) = HASHBYTES ('sha1', b)
Demetris Leptos

3

Ви можете визначити attributeяк BINARYабо використовувати INSTRабо STRCMPвиконувати пошук.


Здається, ця відповідь не стосується SQL Server за тегом питання. У цій СУБД відсутні ці функції INSTRта STRCMPфункції.
Йонас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.