Eu tenho uma função que retorna cinco caracteres com maiúsculas e minúsculas. Se eu fizer uma consulta nessa string, ele retornará o valor, independentemente do caso.
Como posso fazer com que as consultas de string do MySQL sejam sensíveis a maiúsculas e minúsculas?
mysql
sql
interop
case-sensitive
string-comparison
StevenB
fonte
fonte
Respostas:
http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html
fonte
SELECT 'email' COLLATE utf8_bin = 'Email'
A boa notícia é que, se você precisar fazer uma consulta que diferencia maiúsculas de minúsculas, é muito fácil:
fonte
convert(char(0x65,0xcc,0x88) using utf8)
(ou seja,e
com¨
adição) econvert(char(0xc3,0xab) using utf8)
(ou sejaë
), mas a adição asBINARY
tornará desiguais.Resposta postada por Craig White, tem grande penalização de desempenho
porque não usa índices. Portanto, você precisa alterar a ordenação da tabela como mencionado aqui https://dev.mysql.com/doc/refman/5.7/en/case-sensitivity.html .
OU
Correção mais fácil, você deve usar um BINÁRIO de valor.
Por exemplo.
VS
1 linha no conjunto (0,00 s)
fonte
Em vez de usar o operador =, convém usar LIKE ou LIKE BINARY
Vai levar 'a' e não 'A' em sua condição
fonte
Para usar um índice antes de usar o BINARY, você pode fazer algo assim se tiver tabelas grandes.
A subconsulta resultaria em um subconjunto que não diferencia maiúsculas de minúsculas, do qual você seleciona a única correspondência que diferencia maiúsculas de minúsculas.
fonte
A maneira mais correta de executar uma comparação de cadeias com distinção entre maiúsculas e minúsculas sem alterar o agrupamento da coluna que está sendo consultada é especificar explicitamente um conjunto de caracteres e agrupamento para o valor ao qual a coluna está sendo comparada.
Por que não usar
binary
?O uso do
binary
operador é desaconselhável, pois compara os bytes reais das seqüências codificadas. Se você comparar os bytes reais de duas cadeias codificadas usando o conjunto de caracteres diferentes, duas cadeias que devem ser consideradas iguais podem não ser iguais. Por exemplo, se você possui uma coluna que usa olatin1
conjunto de caracteres e seu servidor / sessão éutf8mb4
, quando você compara a coluna com uma sequência que contém um acento como 'café', ela não corresponde às linhas que contêm a mesma sequência! Isto porque, emlatin1
E é codificado como o byte0xE9
, mas emutf8
que é dois bytes:0xC3A9
.Por que usar
convert
tão bem quantocollate
?Os agrupamentos devem corresponder ao conjunto de caracteres. Portanto, se seu servidor ou sessão estiver configurado para usar o
latin1
conjunto de caracteres, você deve usar,collate latin1_bin
mas se seu conjunto de caracteres estiver,utf8mb4
deverá usarcollate utf8mb4_bin
. Portanto, a solução mais robusta é sempre converter o valor no conjunto de caracteres mais flexível e usar o agrupamento binário para esse conjunto de caracteres.Por que aplicar o
convert
ecollate
ao valor e não à coluna?Quando você aplica qualquer função de transformação a uma coluna antes de fazer uma comparação, impede que o mecanismo de consulta use um índice, se houver algum para a coluna, o que poderia diminuir drasticamente a sua consulta. Portanto, é sempre melhor transformar o valor sempre que possível. Quando uma comparação é realizada entre dois valores de sequência e um deles possui um agrupamento especificado explicitamente, o mecanismo de consulta usará o agrupamento explícito, independentemente de qual valor é aplicado.
Sensibilidade ao acento
É importante observar que o MySql não apenas diferencia maiúsculas de minúsculas para colunas usando um
_ci
agrupamento (que normalmente é o padrão), mas também não diferencia sotaque . Isso significa isso'é' = 'e'
. O uso de um agrupamento binário (ou obinary
operador) fará com que as comparações de string sejam sensíveis ao acento e também ao caso.O que é
utf8mb4
?O
utf8
conjunto de caracteres no MySql é um aliasutf8mb3
que foi descontinuado nas versões recentes porque não suporta caracteres de 4 bytes (o que é importante para a codificação de strings como 🐈). Se você deseja usar a codificação de caracteres UTF8 com o MySql, deve usar outf8mb4
charset.fonte
A seguir, versões do MySQL iguais ou superiores a 5,5.
Adicione ao /etc/mysql/my.cnf
Todos os outros agrupamentos que tentei pareciam fazer distinção entre maiúsculas e minúsculas, apenas "utf8_bin" funcionava.
Não esqueça de reiniciar o mysql depois disso:
De acordo com http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html , também há um "latin1_bin".
O "utf8_general_cs" não foi aceito pela inicialização do mysql. (Li "_cs" como "diferencia maiúsculas de minúsculas" - ???).
fonte
Você pode usar BINARY para diferenciar maiúsculas de minúsculas assim
infelizmente esse sql não pode usar o índice, você sofrerá um impacto no desempenho em consultas dependentes desse índice
Felizmente, tenho alguns truques para resolver este problema
fonte
Excelente!
Eu compartilho com você o código de uma função que compara senhas:
fonte
declare pSuccess BINARY;
no inícioNão há necessidade de alterar nada no nível do banco de dados, apenas as alterações no SQL Query que funcionarão.
Exemplo -
"SELECT * FROM <TABLE> where userId = '" + iv_userId + "' AND password = BINARY '" + iv_password + "'";
A palavra-chave binária fará distinção entre maiúsculas e minúsculas.
fonte
O mysql não diferencia maiúsculas de minúsculas por padrão, tente alterar o agrupamento de idiomas para
latin1_general_cs
fonte