Estou trabalhando com um banco de dados MySQL que possui alguns dados importados do Excel . Os dados contêm caracteres não ASCII (traços, etc.), bem como retornos de carro ocultos ou avanços de linha. Existe uma maneira de encontrar esses registros usando o MySQL?
mysql
character-encoding
Ed Mays
fonte
fonte
Respostas:
Depende exatamente do que você está definindo como "ASCII", mas eu sugiro tentar uma variante de uma consulta como esta:
Essa consulta retornará todas as linhas em que columnToCheck contém caracteres não alfanuméricos. Se você tiver outros caracteres aceitáveis, adicione-os à classe de caracteres na expressão regular. Por exemplo, se pontos, vírgulas e hífens estiverem OK, altere a consulta para:
A página mais relevante da documentação do MySQL é provavelmente 12.5.2 Expressões regulares .
fonte
SELECT * FROM tbl WHERE colname NOT REGEXP '^[A-Za-z0-9\.,@&\(\) \-]*$';
O MySQL fornece gerenciamento abrangente de conjunto de caracteres que pode ajudar com esse tipo de problema.
A
CONVERT(col USING charset)
função transforma os caracteres não conversíveis em caracteres de substituição. Em seguida, o texto convertido e não convertido será desigual.Veja isso para mais discussão. https://dev.mysql.com/doc/refman/8.0/en/charset-repertoire.html
Você pode usar qualquer nome de conjunto de caracteres que desejar no lugar de ASCII. Por exemplo, se você deseja descobrir quais caracteres não serão renderizados corretamente na página de código 1257 (lituano, letão, estoniano), use
CONVERT(columnToCheck USING cp1257)
fonte
Você pode definir ASCII como todos os caracteres que tenham um valor decimal de 0 a 127 (0x00 - 0x7F) e localizar colunas com caracteres não ASCII usando a consulta a seguir
Essa foi a consulta mais abrangente que eu pude fazer.
fonte
SELECT * FROM table WHERE LENGTH( column ) != CHAR_LENGTH( column )
'ā'
(codificada pela sequência de bytes0x0101
) - seria considerada "ASCII" usando este teste: um falso negativo ; de fato, alguns conjuntos de caracteres não codificam caracteres ASCII dentro0x00
dos quais0x7f
essa solução produziria um falso positivo. NÃO CONFIE NESTA RESPOSTA!LENGTH(column)
, será um múltiplo constante,CHAR_LENGTH(column)
independentemente do valor.Provavelmente é isso que você está procurando:
Ele deve retornar todas as linhas em que COLUMN contém caracteres não ASCII (ou caracteres ASCII não imprimíveis, como nova linha).
fonte
REGEXP
eRLIKE
funcionam de maneira byte, portanto, não são seguros para vários bytes e podem produzir resultados inesperados com conjuntos de caracteres de vários bytes. Além disso, esses operadores comparam caracteres por seus valores de bytes e caracteres acentuados podem não são considerados iguais mesmo se um determinado trata de agrupamento-los como iguais. "Um caractere ausente dos exemplos de todos acima é o caractere de terminação (\ 0). Isso é invisível para a saída do console do MySQL e não pode ser descoberto por nenhuma das consultas mencionadas anteriormente. A consulta para encontrá-lo é simplesmente:
fonte
Com base na resposta correta, mas levando em consideração os caracteres de controle ASCII, a solução que funcionou para mim é a seguinte:
Ele faz o mesmo: pesquisa violações do intervalo ASCII em uma coluna, mas permite pesquisar caracteres de controle também, pois ele usa notação hexadecimal para pontos de código. Como não há comparação ou conversão (diferente da resposta de @ Ollie), isso também deve ser significativamente mais rápido. (Especialmente se o MySQL fizer o encerramento antecipado na consulta regex, o que definitivamente deveria.)
Também evita retornar campos com comprimento zero. Se você deseja uma versão um pouco mais longa que possa ter um desempenho melhor, use-a:
Ele faz uma verificação separada do comprimento para evitar resultados de comprimento zero, sem considerá-los para um passe de regex. Dependendo do número de entradas de tamanho zero que você possui, isso pode ser significativamente mais rápido.
Observe que, se o conjunto de caracteres padrão for algo bizarro, em que 0x00-0xFF não mapeie para os mesmos valores que ASCII (existe um conjunto de caracteres em algum lugar?), Isso retornaria um falso positivo. Caso contrário, aproveite!
fonte
REGEXP
está verificando. Por isso, é garantido que sempre corresponda. Também^$
provavelmente não é o que você queria.Tente usar esta consulta para pesquisar registros de caracteres especiais
fonte
A resposta de @ zende foi a única que cobriu as colunas com uma mistura de caracteres ascii e não ascii, mas também tinha essa coisa hexadecimal problemática. Eu usei isso:
fonte
No Oracle, podemos usar abaixo.
fonte
para esta pergunta, também podemos usar este método:
Pergunta do sql zoo:
encontre todos os detalhes do prêmio ganho por PETER GRÜNBERG
Caracteres não ASCII
ans: selecione * do nobel onde o vencedor gosta de 'P% GR% _% berg';
fonte