Làm cách nào để thực hiện tìm kiếm phân biệt chữ hoa chữ thường trong mệnh đề WHERE (Tôi đang sử dụng SQL Server)?


150

Tôi muốn thực hiện một tìm kiếm phân biệt chữ hoa chữ thường trong truy vấn SQL của tôi. Nhưng theo mặc định, SQL Server không xem xét trường hợp của chuỗi.

Bất kỳ ý tưởng về cách thực hiện một tìm kiếm phân biệt chữ hoa chữ thường trong truy vấn SQL?

Câu trả lời:


174

Có thể được thực hiện thông qua việc thay đổi Collation . Theo mặc định, nó là trường hợp không nhạy cảm.

Trích từ liên kết:

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

Hoặc, thay đổi các cột để phân biệt chữ hoa chữ thường .


2
Làm thế nào để sử dụng khi chúng ta có thay thế =. như WHERE CustID trong (@CustID)
rinuthomaz

Đối chiếu hoạt động trong hầu hết các trường hợp, nhưng nếu bạn có các ký tự ngôn ngữ khác trong dữ liệu của mình, nó sẽ trả về kết quả dương tính giả: /schwarz-weißso với:/schwarz-weiss
Lazlow

162

Bằng cách sử dụng đối chiếu hoặc chuyển sang nhị phân, như thế này:

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 

Sự trùng lặp của tên người dùng / mật khẩu tồn tại để cung cấp cho công cụ khả năng sử dụng các chỉ mục. Đối chiếu ở trên là đối chiếu phân biệt chữ hoa chữ thường, thay đổi thành đối chiếu bạn cần nếu cần.

Việc thứ hai, chuyển sang nhị phân, có thể được thực hiện như thế này:

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
Những người đọc câu hỏi này cũng có thể thấy hữu ích khi đọc cách thay đổi cột thành phân biệt chữ hoa chữ thường để loại bỏ nhu cầu sử dụng đối chiếu trong mệnh đề WHERE. Xem: stackoverflow.com/a/485394/908677
Elijah Lofgren

2
Phương thức cast như phương thức varbinary làm việc cho tôi khi được sử dụng trực tiếp trên cơ sở dữ liệu, nhưng không hoạt động khi gửi cùng một câu lệnh từ một ứng dụng .NET - không biết tại sao. Nhưng phương pháp đối chiếu đã làm việc tốt.
Doug

1
Câu trả lời này sẽ là hoàn hảo nếu nó bao gồm một lời giải thích về nơi đặt cụm từ được tìm kiếm, nghĩa là nơi cụm từ tương tự như like "*word or phrase*"tìm kiếm SQL thông thường sẽ được chèn vào.
Người đàn ông đóng hộp

@CnedMan - Bạn có thể sử dụng giải pháp đối chiếu ở trên theo cùng một cách với câu lệnh THÍCH. Chỉ cần thực hiện các thao tác sau để trả về tất cả chữ hoa 'D. "CHỌN * TỪ MỘT SỐ WHERE Cột Tên như '% D%' THU THẬP SQL_Latin1_General_CP1_CS_AS"
Radderz

Nó không hoạt động với bảng chữ cái Séc. Đã kiểm tra từ: 'ukázka'. Nó nằm trong bảng dưới dạng một từ đơn lẻ trong một cột, nhưng tìm kiếm của bạn không tìm thấy nó.
Jan Macháček

14

Bạn có thể thực hiện truy vấn bằng cách chuyển đổi sang varbinary - rất dễ dàng. Thí dụ:

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

2
Nó không hoạt động với bảng chữ cái Séc. Đã kiểm tra từ: 'ukázka'. Nó nằm trong bảng dưới dạng một từ đơn lẻ trong một cột, nhưng tìm kiếm của bạn không tìm thấy nó.
Jan Macháček

7

SỬ DỤNG BINary_CHECKSUM

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

3
Điều này có nghĩa là, nó không còn là một so sánh chính xác? Đôi khi có thể trả về sự thật rằng chúng không thực sự giống nhau?
O'Rooney

3
Tôi đồng ý @ O'Rooney điều này sẽ nhân dịp trả lại dương tính giả.
Des Horsley

5

sử dụng 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

... trong mệnh đề where

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

hoặc để tìm một giá trị

declare @value_b nvarchar(1) = 'A'

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

-- output:
-- A = A

5

sử dụng Latin1_General_CS làm đối chiếu của bạn trong db sql của bạn


2

Trong MySQL nếu bạn không muốn thay đổi đối chiếu và muốn thực hiện tìm kiếm phân biệt chữ hoa chữ thường thì chỉ cần sử dụng từ khóa nhị phân như thế này:

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

2
Đó không phải là một truy vấn SQL Server hợp lệ. Tôi nghĩ đó là MySQL
Jon Tirjan 19/07/17

2
Hoạt động hoàn hảo trên MySQL
WM

1
select * from incidentsnew1 
where BINARY_CHECKSUM(CloseBy) = BINARY_CHECKSUM(Upper(CloseBy))

-4

Giống như những người khác nói, bạn có thể thực hiện tìm kiếm phân biệt chữ hoa chữ thường. Hoặc chỉ thay đổi định dạng đối chiếu của một cột được chỉ định như tôi. Đối với các cột Người dùng / Mật khẩu trong cơ sở dữ liệu của tôi, tôi thay đổi chúng thành đối chiếu thông qua lệnh sau:

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

KHÔNG lưu trữ mật khẩu dưới dạng văn bản gốc! Chúng nên được băm và ướp muối, và sau đó so sánh là về băm và muối! Đây chỉ đơn giản là một câu trả lời khủng khiếp!
Nelson
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.