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?

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 .


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 

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

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)

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

5

gunakan Latin1_General_CS sebagai collation Anda di sql db


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

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

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

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.