Como fazer uma pesquisa que diferencia maiúsculas de minúsculas na cláusula WHERE (estou usando o SQL Server)?

150

Quero fazer uma pesquisa que diferencia maiúsculas de minúsculas na minha consulta SQL. Mas, por padrão, o SQL Server não considera o caso das seqüências de caracteres.

Alguma idéia de como fazer uma pesquisa que diferencia maiúsculas de minúsculas na consulta SQL?

Veera
fonte

Respostas:

174

Pode ser feito alterando o agrupamento . Por padrão, não faz distinção entre maiúsculas e minúsculas.

Trecho do 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

Ou altere as colunas para fazer distinção entre maiúsculas e minúsculas .

Ashish Jain
fonte
2
Como usar quando temos em vez disso. como WHERE CustID em (@CustID)
rinuthomaz
O agrupamento funciona na maioria dos casos, mas se você tiver outros caracteres de idioma em seus dados, retornará falsos positivos: /schwarz-weißversus:/schwarz-weiss
Lazlow
162

Usando agrupamento ou conversão para binário, assim:

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 

A duplicação de nome de usuário / senha existe para dar ao mecanismo a possibilidade de usar índices. O agrupamento acima é um agrupamento que diferencia maiúsculas de minúsculas. Altere para o que você precisa, se necessário.

O segundo, convertendo para binário, poderia ser feito assim:

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
fonte
13
As pessoas que leem essa pergunta também podem achar útil ler como alterar a própria coluna para fazer distinção entre maiúsculas e minúsculas, o que elimina a necessidade de usar agrupamento na cláusula WHERE. Veja: stackoverflow.com/a/485394/908677
Elijah Lofgren
2
O método cast como varbinário funcionou para mim quando usado diretamente no banco de dados, mas não funcionou ao enviar a mesma instrução de um aplicativo .NET - não faço ideia do porquê. Mas o método de agrupamento funcionou bem.
Doug
1
Essa resposta seria perfeita se incluísse uma explicação de onde colocar o termo pesquisado, ou seja, onde like "*word or phrase*"seria inserida a frase semelhante a uma pesquisa SQL regular .
Homem enlatado
@ CannedMan - Você pode usar a solução de agrupamento acima da mesma maneira com a instrução LIKE. Simplesmente faça o seguinte para retornar todos os 'D' maiúsculos. "SELECT * FROM SomeTable WHERE Nome da coluna como '% D%' COLLATE SQL_Latin1_General_CP1_CS_AS"
Radderz
Não funciona com alfabeto checo. Palavra testada: 'ukázka'. Está na tabela como uma palavra em uma coluna, mas sua pesquisa não a encontrou.
Jan Macháček
14

Você pode fazer a consulta usando convert para varbinary - é muito fácil. Exemplo:

Select * from your_table where convert(varbinary, your_column) = convert(varbinary, 'aBcD') 
Juan Carlos Velez
fonte
2
Não funciona com alfabeto checo. Palavra testada: 'ukázka'. Está na tabela como uma palavra em uma coluna, mas sua pesquisa não a encontrou.
Jan Macháček
7

USE BINARY_CHECKSUM

SELECT 
FROM Users
WHERE   
    BINARY_CHECKSUM(Username) = BINARY_CHECKSUM(@Username)
    AND BINARY_CHECKSUM(Password) = BINARY_CHECKSUM(@Password)
Sandeep
fonte
3
Isso não significa que não é mais uma comparação exata? Às vezes, pode ser verdade que eles não são realmente iguais?
O'Rooney
3
Concordo @ O'Rooney, que ocasionalmente retornará falsos positivos.
Des Horsley
5

use 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

... na cláusula 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

ou para encontrar um valor

declare @value_b nvarchar(1) = 'A'

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

-- output:
-- A = A
Dub
fonte
5

use Latin1_General_CS como seu agrupamento em seu sql db

Blake
fonte
2

No MySQL, se você não deseja alterar o agrupamento e deseja executar pesquisa com distinção entre maiúsculas e minúsculas, basta usar a palavra-chave binária como esta:

SELECT * FROM table_name WHERE binary username=@search_parameter and binary password=@search_parameter
Sumit Joshi
fonte
2
Essa não é uma consulta válida do SQL Server. Eu acho que isso é MySQL
Jon Tirjan
2
Funciona perfeitamente no MySQL
WM
1
select * from incidentsnew1 
where BINARY_CHECKSUM(CloseBy) = BINARY_CHECKSUM(Upper(CloseBy))
Hemant yadav
fonte
-4

Assim como outros disseram, você pode realizar uma pesquisa que diferencia maiúsculas de minúsculas. Ou apenas altere o formato de agrupamento de uma coluna especificada como eu. Para as colunas Usuário / Senha no meu banco de dados, eu as altero para agrupamento através do seguinte comando:

ALTER TABLE `UserAuthentication` CHANGE `Password` `Password` VARCHAR(255) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL;
Gfast2
fonte
NÃO armazene senhas como texto sem formatação! Eles deveriam ter sido misturados e salgados, e então a comparação é sobre o hash e o sal! Esta é simplesmente uma resposta terrível!
Nelson