Bagaimana cara melakukan pencarian sensitif huruf dalam klausa WHERE (Saya menggunakan SQL Server)?

150

Saya ingin melakukan pencarian case sensitif dalam permintaan SQL saya. Tetapi secara default, SQL Server tidak mempertimbangkan kasus string.

Adakah ide tentang bagaimana melakukan pencarian case-sensitive dalam SQL query?

Veera
sumber

Jawaban:

174

Dapat dilakukan dengan mengubah Collation . Secara default itu tidak sensitif huruf.

Kutipan dari tautan:

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

Atau, ubah kolom menjadi case sensitive .

Ashish Jain
sumber
2
Bagaimana cara menggunakan saat kita memiliki gantinya =. seperti WHERE CustID in (@CustID)
rinuthomaz
Kolasi berfungsi untuk sebagian besar kasus, tetapi jika Anda memiliki karakter bahasa lain di data Anda, itu akan menghasilkan positif palsu: /schwarz-weißversus:/schwarz-weiss
Lazlow
162

Dengan menggunakan collation atau casting ke biner, seperti ini:

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 

Duplikasi nama pengguna / kata sandi ada untuk memberi mesin kemungkinan menggunakan indeks. Susunan di atas adalah susunan Huruf Sensitif, ubah ke yang Anda butuhkan jika perlu.

Yang kedua, casting ke biner, bisa dilakukan seperti ini:

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
sumber
13
Orang-orang yang membaca pertanyaan ini mungkin juga berguna untuk membaca bagaimana mengubah kolom itu sendiri menjadi case-sensitive yang menghilangkan kebutuhan untuk menggunakan collation dalam klausa WHERE. Lihat: stackoverflow.com/a/485394/908677
Elijah Lofgren
2
Para pemain sebagai metode varbinary bekerja untuk saya ketika digunakan langsung pada database, tetapi tidak berfungsi ketika mengirim pernyataan yang sama dari aplikasi .NET - tidak tahu mengapa. Tetapi metode susun bekerja dengan baik.
Doug
1
Jawaban ini akan sempurna jika termasuk penjelasan tentang di mana harus meletakkan istilah yang dicari, yaitu di mana frasa yang mirip dengan like "*word or phrase*"pencarian SQL biasa akan dimasukkan.
Canned Man
@CannedMan - Anda dapat menggunakan solusi susun di atas dengan cara yang sama dengan pernyataan LIKE. Cukup lakukan hal berikut untuk mengembalikan semua huruf besar 'D's. "SELECT * FROM SomeTable WHERE ColumnName like '% D%' COLLATE SQL_Latin1_General_CP1_CS_AS"
Radderz
Itu tidak bekerja dengan alfabet ceko. Kata yang diuji: 'ukázka'. Itu ada di tabel sebagai kata menghanguskan dalam sebuah kolom, tetapi pencarian Anda tidak menemukannya.
Jan Machacek
14

Anda dapat membuat kueri menggunakan convert ke varbinary - sangat mudah. Contoh:

Select * from your_table where convert(varbinary, your_column) = convert(varbinary, 'aBcD') 
Juan Carlos Velez
sumber
2
Itu tidak bekerja dengan alfabet ceko. Kata yang diuji: 'ukázka'. Itu ada di tabel sebagai kata menghanguskan dalam sebuah kolom, tetapi pencarian Anda tidak menemukannya.
Jan Machacek
7

GUNAKAN BINARY_CHECKSUM

SELECT 
FROM Users
WHERE   
    BINARY_CHECKSUM(Username) = BINARY_CHECKSUM(@Username)
    AND BINARY_CHECKSUM(Password) = BINARY_CHECKSUM(@Password)
Sandeep
sumber
3
Bukankah ini berarti, bahwa ini bukan lagi perbandingan yang tepat? Mungkin ada kalanya itu mengembalikan benar bahwa mereka sebenarnya tidak sama?
O'Rooney
3
Saya setuju @ O'Rooney ini pada kesempatan akan mengembalikan positif palsu.
Des Horsley
5

gunakan 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

... di mana klausa

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

atau untuk menemukan nilai

declare @value_b nvarchar(1) = 'A'

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

-- output:
-- A = A
Menjuluki
sumber
5

gunakan Latin1_General_CS sebagai collation Anda di sql db

blake
sumber
2

Di MySQL jika Anda tidak ingin mengubah collation dan ingin melakukan pencarian case sensitif maka gunakan saja kata kunci biner seperti ini:

SELECT * FROM table_name WHERE binary username=@search_parameter and binary password=@search_parameter
Sumit Joshi
sumber
2
Itu bukan permintaan SQL Server yang valid. Saya pikir itu MySQL
Jon Tirjan
2
Bekerja dengan sempurna di MySQL
WM
1
select * from incidentsnew1 
where BINARY_CHECKSUM(CloseBy) = BINARY_CHECKSUM(Upper(CloseBy))
Hemant yadav
sumber
-4

Seperti yang dikatakan orang lain, Anda dapat melakukan pencarian case sensitif. Atau cukup ubah format pemeriksaan kolom yang ditentukan seperti saya. Untuk kolom Pengguna / Kata Sandi di basis data saya, saya mengubahnya ke susunan melalui perintah berikut:

ALTER TABLE `UserAuthentication` CHANGE `Password` `Password` VARCHAR(255) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL;
Gfast2
sumber
JANGAN menyimpan kata sandi sebagai plaintext! Mereka seharusnya di-hash dan diberi garam, lalu perbandingannya adalah hash dan garam! Ini hanyalah jawaban yang mengerikan!
Nelson