Jak przeprowadzić wyszukiwanie z uwzględnieniem wielkości liter w klauzuli WHERE (używam SQL Server)?

150

Chcę przeprowadzić wyszukiwanie z uwzględnieniem wielkości liter w moim zapytaniu SQL. Ale domyślnie SQL Server nie bierze pod uwagę wielkości liter.

Masz pomysł, jak wyszukiwać w zapytaniach SQL z uwzględnieniem wielkości liter?

Veera
źródło

Odpowiedzi:

174

Można to zrobić poprzez zmianę sortowania . Domyślnie wielkość liter nie jest rozróżniana.

Wyciąg z linku:

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

Lub zmień kolumny, aby uwzględniały wielkość liter .

Ashish Jain
źródło
2
Jak używać, gdy zamiast tego mamy =. jak WHERE CustID in (@CustID)
rinuthomaz
Sortowanie działa w większości przypadków, ale jeśli w danych znajdują się znaki innego języka, zwróci ono fałszywe alarmy: w /schwarz-weißporównaniu z:/schwarz-weiss
Lazlow
162

Używając sortowania lub rzutowania na binarny, na przykład:

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 

Istnieje zduplikowanie nazwy użytkownika / hasła, aby umożliwić silnikowi korzystanie z indeksów. Powyższe zestawienie jest sortowaniem z uwzględnieniem wielkości liter, w razie potrzeby zmień na takie, które potrzebujesz.

Drugie, rzutowanie na binarne, można zrobić w ten sposób:

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 
Jonas Lincoln
źródło
13
Osoby czytające to pytanie mogą również uznać za przydatne przeczytanie, jak zmienić samą kolumnę, aby uwzględniała wielkość liter, co eliminuje potrzebę stosowania sortowania w klauzuli WHERE. Zobacz: stackoverflow.com/a/485394/908677
Elijah Lofgren
2
Metoda rzutowania jako varbinary działała u mnie, gdy była używana bezpośrednio w bazie danych, ale nie działała podczas wysyłania tej samej instrukcji z aplikacji .NET - nie mam pojęcia dlaczego. Ale metoda sortowania działała dobrze.
Doug
1
Ta odpowiedź byłaby idealna, gdyby zawierała wyjaśnienie, gdzie umieścić szukany termin, tj. Gdzie like "*word or phrase*"zostanie wstawiona fraza podobna do zwykłego wyszukiwania SQL.
Canned Man
@CannedMan - Możesz użyć powyższego rozwiązania sortowania w ten sam sposób z instrukcją LIKE. Po prostu wykonaj następujące czynności, aby zwrócić wszystkie wielkie litery „D”. „SELECT * FROM SomeTable WHERE ColumnName, na przykład„% D% ”COLLATE SQL_Latin1_General_CP1_CS_AS”
Radderz
Nie działa z czeskim alfabetem. Testowane słowo: „ukázka”. Znajduje się w tabeli jako pojedyncze słowo w kolumnie, ale wyszukiwanie go nie znalazło.
Jan Macháček
14

Możesz wykonać zapytanie za pomocą Convert to varbinary - to bardzo proste. Przykład:

Select * from your_table where convert(varbinary, your_column) = convert(varbinary, 'aBcD') 
Juan Carlos Velez
źródło
2
Nie działa z czeskim alfabetem. Testowane słowo: „ukázka”. Znajduje się w tabeli jako pojedyncze słowo w kolumnie, ale wyszukiwanie go nie znalazło.
Jan Macháček
7

UŻYJ BINARY_CHECKSUM

SELECT 
FROM Users
WHERE   
    BINARY_CHECKSUM(Username) = BINARY_CHECKSUM(@Username)
    AND BINARY_CHECKSUM(Password) = BINARY_CHECKSUM(@Password)
Sandeep
źródło
3
Czy nie oznaczałoby to, że nie jest to już dokładne porównanie? Czasami może się zdarzyć, że wraca prawda, że ​​tak naprawdę nie są takie same?
O'Rooney
3
Zgadzam się, @ O'Rooney, że czasami zwróci to fałszywe alarmy.
Des Horsley
5

użyj 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

... w gdzie klauzula

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

lub znaleźć wartość

declare @value_b nvarchar(1) = 'A'

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

-- output:
-- A = A
Zdubbingować
źródło
5

użyj Latin1_General_CS jako sortowania w bazie danych sql

blake
źródło
2

W MySQL, jeśli nie chcesz zmieniać sortowania i chcesz wyszukiwać z uwzględnieniem wielkości liter, użyj po prostu binarnego słowa kluczowego w następujący sposób:

SELECT * FROM table_name WHERE binary username=@search_parameter and binary password=@search_parameter
Sumit Joshi
źródło
2
To nie jest prawidłowe zapytanie SQL Server. Myślę, że to MySQL
Jon Tirjan
2
Działa idealnie na MySQL
WM
1
select * from incidentsnew1 
where BINARY_CHECKSUM(CloseBy) = BINARY_CHECKSUM(Upper(CloseBy))
Hemant yadav
źródło
-4

Tak jak powiedzieli inni, możesz przeprowadzić wyszukiwanie z uwzględnieniem wielkości liter. Lub po prostu zmień format sortowania określonej kolumny jako ja. W przypadku kolumn użytkownika / hasła w mojej bazie danych zmieniam je na sortowanie za pomocą następującego polecenia:

ALTER TABLE `UserAuthentication` CHANGE `Password` `Password` VARCHAR(255) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL;
Gfast2
źródło
NIE przechowuj haseł jako zwykłego tekstu! Powinny być zasolone i zasolone, a potem porównanie dotyczy haszu i soli! To po prostu okropna odpowiedź!
Nelson