Come eseguire una ricerca con distinzione tra maiuscole e minuscole nella clausola WHERE (sto usando SQL Server)?


150

Voglio fare una ricerca con distinzione tra maiuscole e minuscole nella mia query SQL. Ma per impostazione predefinita, SQL Server non considera il caso delle stringhe.

Qualche idea su come eseguire una ricerca con distinzione tra maiuscole e minuscole nella query SQL?

Risposte:


174

Può essere fatto cambiando la collazione . Di default non fa distinzione tra maiuscole e minuscole.

Estratto dal link:

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

In alternativa, modifica le colonne in modo che facciano distinzione tra maiuscole e minuscole .


2
Come usare quando abbiamo invece =. come WHERE CustID in (@CustID)
rinuthomaz,

Le regole di confronto funzionano nella maggior parte dei casi, ma se hai altri caratteri linguistici nei tuoi dati, verranno restituiti falsi positivi: /schwarz-weißcontro:/schwarz-weiss
Lazlow,

162

Usando fascicolazione o casting in binario, in questo modo:

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 

La duplicazione di nome utente / password esiste per dare al motore la possibilità di utilizzare gli indici. Le regole di confronto sopra riportate sono una distinzione maiuscole / minuscole, se necessario cambiano con quella necessaria.

Il secondo, eseguendo il casting in binario, potrebbe essere fatto in questo modo:

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
Le persone che leggono questa domanda possono anche trovare utile leggere come modificare la colonna stessa in modo che faccia distinzione tra maiuscole e minuscole, il che elimina la necessità di utilizzare le regole di confronto nella clausola WHERE. Vedi: stackoverflow.com/a/485394/908677
Elia Lofgren

2
Il cast come metodo varbinary ha funzionato per me quando è stato utilizzato direttamente sul database, ma non ha funzionato durante l'invio della stessa istruzione da un'applicazione .NET - non ho idea del perché. Ma il metodo di fascicolazione ha funzionato bene.
Doug,

1
Questa risposta sarebbe perfetta se includesse una spiegazione di dove inserire il termine cercato, ovvero dove like "*word or phrase*"verrebbe inserita la frase simile a una normale ricerca SQL.
Uomo in scatola

@CannedMan - È possibile utilizzare la soluzione di fascicolazione sopra descritta allo stesso modo con l'istruzione LIKE. Basta fare quanto segue per restituire tutte le "D" maiuscole. "SELEZIONA * DA SomeTable DOVE Nome colonna come '% D%' COLLATE SQL_Latin1_General_CP1_CS_AS"
Radderz

Non funziona con l'alfabeto ceco. Parola testata: "ukázka". È nella tabella come una singola parola in una colonna, ma la tua ricerca non l'ha trovata.
Jan Macháček,

14

È possibile effettuare la query utilizzando convert in varbinary: è molto semplice. Esempio:

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

2
Non funziona con l'alfabeto ceco. Parola testata: "ukázka". È nella tabella come una singola parola in una colonna, ma la tua ricerca non l'ha trovata.
Jan Macháček,

7

USA BINARY_CHECKSUM

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

3
Questo non significherebbe che non è più un confronto esatto? A volte potrebbe essere vero che in realtà non sono uguali?
O'Rooney,

3
Sono d'accordo @ O'Rooney che a volte restituirà falsi positivi.
Des Horsley,

5

usa 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

... in cui clausola

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

o per trovare un valore

declare @value_b nvarchar(1) = 'A'

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

-- output:
-- A = A

5

usa Latin1_General_CS come collation nel tuo sql db


2

In MySQL se non si desidera modificare le regole di confronto e si desidera eseguire ricerche con distinzione tra maiuscole e minuscole, utilizzare semplicemente una parola chiave binaria come questa:

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

2
Questa non è una query valida di SQL Server. Penso che sia MySQL
Jon Tirjan,

2
Funziona perfettamente su MySQL
WM,

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

-4

Proprio come altri hanno detto, è possibile eseguire una ricerca con distinzione tra maiuscole e minuscole. O semplicemente cambia il formato delle regole di confronto di una colonna specificata come me. Per le colonne Utente / Password nel mio database, le cambio in regole di confronto tramite il comando seguente:

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

NON archiviare le password come testo normale! Avrebbero dovuto essere hash e salati, e quindi il confronto è sull'hash e sul sale! Questa è semplicemente una risposta terribile!
Nelson
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.