SQL String Sensitive Compare

234

Como você compara seqüências de caracteres para que a comparação seja verdadeira apenas se os casos de cada uma delas também forem iguais. Por exemplo:

Select * from a_table where attribute = 'k'

... retornará uma linha com um atributo 'K'. Eu não quero esse comportamento.

amccormack
fonte
Pode não ser o que você precisa, mas você pode alterar o agrupamento ou usar um agrupamento específico na sua consulta.
Kane
7
Qual produto SQL?
onedaywhen

Respostas:

388
Select * from a_table where attribute = 'k' COLLATE Latin1_General_CS_AS 

Fiz o truque.

amccormack
fonte
4
Normalmente eu usaria Latin1_General_Bin
gbn 19/10/10
3
Sim, a abordagem padrão é usar um agrupamento que não diferencia maiúsculas de minúsculas, embora os agrupamentos em si sejam específicos do fornecedor. A sua sintaxe do SQL Server?
onedaywhen
No meu caso, tenho 1 coluna no meu banco de dados que faz distinção entre maiúsculas e minúsculas. Eu precisava compará-lo com uma coluna padrão (CI). Eu usei uma variação deste WHERE Foo.Bar = (Baz.Bar COLLATE Latin1_General_CS_AS)
Hipnovírus
2
Obrigado, mas o que é Latin1_General_CS_AS ?? É uma palavra-chave especial?
Vijay Singh Rana
2
@VijaySinghRana Latin1_General_CS_ASé uma especificação do agrupamento. Agrupamento refere-se a um conjunto de regras que determinam como os dados são classificados e comparados. Veja esta página para mais informações.
amccormack
51

Você também pode converter esse atributo como distinção entre maiúsculas e minúsculas usando esta sintaxe:

ALTER TABLE Table1
ALTER COLUMN Column1 VARCHAR(200)
COLLATE SQL_Latin1_General_CP1_CS_AS

Agora sua pesquisa diferencia maiúsculas de minúsculas .

Se você deseja tornar a coluna insensível novamente, use

ALTER TABLE Table1
ALTER COLUMN Column1 VARCHAR(200)
COLLATE SQL_Latin1_General_CP1_CI_AS
Jugal
fonte
29

Você pode facilmente converter colunas em VARBINARY (Max Length). O comprimento deve ser o máximo que você espera para evitar uma comparação defeituosa. É o suficiente para definir o comprimento como o comprimento da coluna. A coluna Aparar ajuda a comparar o valor real, exceto que o espaço tem um significado e é valorizado nas colunas da tabela. Esta é uma amostra simples e, como você pode ver, I Aparar o valor das colunas e, em seguida, converter e comparar .:

CONVERT(VARBINARY(250),LTRIM(RTRIM(Column1))) = CONVERT(VARBINARY(250),LTRIM(RTRIM(Column2)))

Espero que esta ajuda.

QMaster
fonte
2
Exatamente o que eu estava procurando. Uma maneira simples de fazer uma comparação única e diferencia maiúsculas de minúsculas para encontrar entradas que contenham caracteres maiúsculos.
Mike D.
20

Assim como outra alternativa, você pode usar HASHBYTES, algo como isto:

SELECT * 
FROM a_table 
WHERE HASHBYTES('sha1', attribute) = HASHBYTES('sha1', 'k')
Dave Sexton
fonte
1
E as colisões? Seria raro, mas eu suponho que haveria várias seqüências de caracteres com o mesmo valor.
David Klempfner 23/11/19
Sim possível, mas extremamente raro em um exemplo de string tão simples que eu teria pensado.
Dave Sexton
@DavidKlempfner, por que não fazer a comparação primeiro e, se corresponderem, verifique também se há hashbytes? Podemos fazer disso uma função e invocá-la como StringsAreCaseSensitiveEqual (a, b) => a = b AND HASHBYTES ('sha1', a) = HASHBYTES ('sha1', b)
Demetris Leptos
3

Você pode definir attributecomo BINARYou usar INSTRou STRCMPpara executar sua pesquisa.

MatTheCat
fonte
Esta resposta não parece ser sobre o SQL Server pela marca de pergunta. Isso DBMS não há estas INSTRe STRCMPfunções.
Jonas