Як здійснити облік у регістрі WHERE (я використовую SQL Server)?


150

Я хочу здійснити регістр пошуку в моєму SQL-запиті. Але за замовчуванням SQL Server не враховує випадок рядків.

Будь-яка ідея про те, як зробити регістр пошуку в регістрі SQL?

Відповіді:


174

Це можна зробити за допомогою зміни Collation . За замовчуванням це нечутливе до регістру.

Витяг із посилання:

SELECT 1
FROM dbo.Customers
WHERE   CustID = @CustID COLLATE SQL_Latin1_General_CP1_CS_AS
    AND CustPassword = @CustPassword COLLATE SQL_Latin1_General_CP1_CS_AS

Або змінити стовпці, щоб вони залежно від регістру .


2
Як використовувати, коли у нас замість =. як WHERE CustID в (@CustID)
rinuthomaz

Впорядкування працює в більшості випадків, але якщо у вас є інші символи мови в ваших даних, він повертає помилкові спрацьовування: /schwarz-weißпроти:/schwarz-weiss
Lazlow

162

Використовуючи зіставлення чи кастинг у двійкове, як це:

SELECT *
FROM Users
WHERE   
    Username = @Username COLLATE SQL_Latin1_General_CP1_CS_AS
    AND Password = @Password COLLATE SQL_Latin1_General_CP1_CS_AS
    AND Username = @Username 
    AND Password = @Password 

Дублювання імені користувача / пароля існує, щоб дати двигуну можливість використовувати індекси. Посилання вище - це порівняльне врахування регістру, якщо необхідно, змініть на необхідне.

Другий, передаваючи бінарне, можна зробити так:

SELECT *
FROM Users
WHERE   
    CAST(Username as varbinary(100)) = CAST(@Username as varbinary))
    AND CAST(Password as varbinary(100)) = CAST(@Password as varbinary(100))
    AND Username = @Username 
    AND Password = @Password 

13
Люди, які читають це запитання, можуть також вважати корисним прочитати, як змінити стовпець, щоб він відрізнявся від регістру, що виключає необхідність використання порівняння в пункті WHERE. Дивіться: stackoverflow.com/a/485394/908677
Ілля Лофгрен

2
Акторський склад як варбінарний метод працював для мене при використанні безпосередньо в базі даних, але не працював при надсиланні того самого заяви з додатку .NET - не знаю чому. Але метод порівняння спрацював чудово.
Дуг

1
Ця відповідь була б ідеальною, якби вона включала пояснення, куди слід поставити шуканий термін, тобто куди like "*word or phrase*"б вставлена фраза, схожа на звичайний пошук у SQL.
консервована людина

@CannedMan - Ви можете використовувати вищезазначене рішення співставлення так само, як з операцією LIKE. Просто виконайте наступне, щоб повернути всі великі регістри "D". "SELECT * OF SomeTable WHERE ColumnName типу"% D% "COLLATE SQL_Latin1_General_CP1_CS_AS"
Radderz

Це не працює з чеським алфавітом. Перевірене слово: 'ukázka'. Це в таблиці як окреме слово в стовпці, але ваш пошук не знайшов його.
Ян Мачачек

14

Ви можете зробити запит за допомогою перетворення на варбінарний - це дуже просто. Приклад:

Select * from your_table where convert(varbinary, your_column) = convert(varbinary, 'aBcD') 

2
Це не працює з чеським алфавітом. Перевірене слово: 'ukázka'. Це в таблиці як окреме слово в стовпці, але ваш пошук не знайшов його.
Ян Мачачек

7

ВИКОРИСТОВУЙТЕ BINARY_CHECKSUM

SELECT 
FROM Users
WHERE   
    BINARY_CHECKSUM(Username) = BINARY_CHECKSUM(@Username)
    AND BINARY_CHECKSUM(Password) = BINARY_CHECKSUM(@Password)

3
Чи не означало це, що це вже не точне порівняння? Може буває, що повертається правда, що вони насправді не однакові?
O'Rooney

3
Я згоден @ O'Rooney, це буде при нагоді повернути помилкові позитиви.
Дес Хорслі

5

використовувати HASHBYTES

declare @first_value nvarchar(1) = 'a'
declare @second_value navarchar(1) = 'A'

if HASHBYTES('SHA1',@first_value) = HASHBYTES('SHA1',@second_value) begin
    print 'equal'
end else begin
    print 'not equal'
end

-- output:
-- not equal

... де пункт

declare @example table (ValueA nvarchar(1), ValueB nvarchar(1))

insert into @example (ValueA, ValueB)
values  ('a', 'A'),
        ('a', 'a'),
        ('a', 'b')

select  ValueA + ' = ' + ValueB
from    @example
where   hashbytes('SHA1', ValueA) = hashbytes('SHA1', ValueB)

-- output:
-- a = a

select  ValueA + ' <> ' + ValueB
from    @example
where   hashbytes('SHA1', ValueA) <> hashbytes('SHA1', ValueB)

-- output:
-- a <> A
-- a <> b

або знайти значення

declare @value_b nvarchar(1) = 'A'

select  ValueB + ' = ' + @value_b
from    @example
where   hashbytes('SHA1', ValueB) = hasbytes('SHA1', @value_b)

-- output:
-- A = A

5

використовуйте Latin1_General_CS для порівняння у вашому sql db


2

У MySQL, якщо ви не хочете змінювати зіставлення і хочете здійснити облік у регістрі, тоді просто використовуйте двійкове ключове слово, як це:

SELECT * FROM table_name WHERE binary username=@search_parameter and binary password=@search_parameter

2
Це недійсний запит на SQL Server. Я думаю, що це MySQL
Джон Тірджан

2
Відмінно працює на MySQL
WM


-4

Як вже говорили інші, ви можете здійснити облік у регістрі. Або просто змінити формат зіставлення вказаного стовпця як я. Для стовпців "Користувач / Пароль" у моїй базі даних я змінюю їх на порівняння за допомогою наступної команди:

ALTER TABLE `UserAuthentication` CHANGE `Password` `Password` VARCHAR(255) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL;

НЕ зберігайте паролі як простий текст! Вони повинні були перетерти і посолити, і тоді порівняння відбувається на хеш-солі! Це просто жахлива відповідь!
Нельсон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.