จะค้นหาแบบตรงตามตัวพิมพ์ใหญ่ใน WHERE clause ได้อย่างไร (ฉันใช้ 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 

มีการทำซ้ำชื่อผู้ใช้ / รหัสผ่านเพื่อให้โปรแกรมสามารถใช้ดัชนีได้ การเปรียบเทียบข้างต้นเป็นการเปรียบเทียบ Case Sensitive เปลี่ยนเป็นสิ่งที่คุณต้องการหากจำเป็น

ประการที่สองการคัดเลือกเป็นไบนารี่สามารถทำได้ดังนี้:

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
Elijah Lofgren

2
วิธีคาสต์เป็น varbinary ทำงานสำหรับฉันเมื่อใช้โดยตรงกับฐานข้อมูล แต่ไม่ทำงานเมื่อส่งคำสั่งเดียวกันจากแอ็พพลิเคชัน. NET - ไม่ทราบสาเหตุ แต่วิธีการเรียงทำงานได้ดี
Doug

1
คำตอบนี้จะสมบูรณ์หากมีคำอธิบายว่าจะใส่คำค้นหาที่ใดเช่นวลีที่คล้ายกับการlike "*word or phrase*"ค้นหา SQL ทั่วไปจะถูกแทรก
ชายกระป๋อง

@CanemanMan - คุณสามารถใช้วิธีแก้ไขปัญหาข้างต้นในลักษณะเดียวกันกับคำสั่ง LIKE เพียงทำสิ่งต่อไปนี้เพื่อส่งคืนตัวพิมพ์ใหญ่ทั้งหมด 'D "SELECT * จาก SomeTable WHERE ColumnName เช่น '% D%' COLLATE SQL_Latin1_General_CP1_CS_AS"
Radderz

มันไม่ทำงานกับตัวอักษรเช็ก คำทดสอบ: 'ukázka' มันอยู่ในตารางเป็นคำเดียวในคอลัมน์ แต่การค้นหาของคุณไม่พบ
Jan Macháček

14

คุณสามารถสร้างแบบสอบถามโดยใช้การแปลงเป็น varbinary - ง่ายมาก ตัวอย่าง:

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

2
มันไม่ทำงานกับตัวอักษรเช็ก คำทดสอบ: 'ukázka' มันอยู่ในตารางเป็นคำเดียวในคอลัมน์ แต่การค้นหาของคุณไม่พบ
Jan Macháček

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 ในบางโอกาสจะได้รับผลบวก
Des Horsley

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


2

ใน MySQL ถ้าคุณไม่ต้องการเปลี่ยนการเรียงและต้องการทำการค้นหาตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ให้ใช้คีย์เวิร์ดbinaryดังนี้

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

2
นั่นไม่ใช่แบบสอบถาม SQL Server ที่ถูกต้อง ฉันคิดว่านั่นคือ MySQL
Jon Tirjan

2
ทำงานได้อย่างสมบูรณ์บน MySQL
WM


-4

อย่างที่คนอื่นพูดคุณสามารถทำการค้นหาแบบตรงตามตัวพิมพ์ หรือเพียงแค่เปลี่ยนรูปแบบการจัดเรียงของคอลัมน์ที่ระบุเป็นฉัน สำหรับคอลัมน์ User / Password ในฐานข้อมูลของฉันฉันเปลี่ยนเป็น collation ผ่านคำสั่งต่อไปนี้:

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

อย่าเก็บรหัสผ่านเป็นข้อความธรรมดา! พวกเขาควรได้รับการแฮชและใส่เกลือแล้วการเปรียบเทียบก็คือกัญชาและเกลือ! นี่เป็นคำตอบที่แย่มาก!
เนลสัน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.