Estoy trabajando con una base de datos MySQL que tiene algunos datos importados de Excel . Los datos contienen caracteres no ASCII (guiones largos, etc.), así como retornos de carro ocultos o avances de línea. ¿Hay alguna manera de encontrar estos registros usando MySQL?
mysql
character-encoding
Ed Mays
fuente
fuente
Respuestas:
Depende exactamente de lo que esté definiendo como "ASCII", pero sugeriría probar una variante de una consulta como esta:
Esa consulta devolverá todas las filas donde columnToCheck contiene caracteres no alfanuméricos. Si tiene otros caracteres que son aceptables, agréguelos a la clase de caracteres en la expresión regular. Por ejemplo, si los puntos, las comas y los guiones están bien, cambie la consulta a:
La página más relevante de la documentación de MySQL es probablemente 12.5.2 Expresiones regulares .
fuente
SELECT * FROM tbl WHERE colname NOT REGEXP '^[A-Za-z0-9\.,@&\(\) \-]*$';
MySQL proporciona una gestión integral del juego de caracteres que puede ayudar con este tipo de problema.
La
CONVERT(col USING charset)
función convierte los caracteres no convertibles en caracteres de reemplazo. Entonces, el texto convertido y no convertido será desigual.Vea esto para más discusión. https://dev.mysql.com/doc/refman/8.0/en/charset-repertoire.html
Puede usar cualquier nombre de juego de caracteres que desee en lugar de ASCII. Por ejemplo, si desea averiguar qué caracteres no se mostrarán correctamente en la página de códigos 1257 (lituano, letón, estonio) use
CONVERT(columnToCheck USING cp1257)
fuente
Puede definir ASCII como todos los caracteres que tienen un valor decimal de 0 a 127 (0x00 - 0x7F) y buscar columnas con caracteres no ASCII utilizando la siguiente consulta
Esta fue la consulta más completa que se me ocurrió.
fuente
SELECT * FROM table WHERE LENGTH( column ) != CHAR_LENGTH( column )
'ā'
(codificada por la secuencia de bytes0x0101
): se consideraría "ASCII" con esta prueba: un falso negativo ; de hecho, algunos conjuntos de caracteres no codifican caracteres ASCII dentro0x00
de los0x7f
cuales esta solución produciría un falso positivo. ¡NO CONFÍE EN ESTA RESPUESTA!LENGTH(column)
lo tanto , serán un múltiplo constanteCHAR_LENGTH(column)
independientemente del valor.Esto es probablemente lo que estás buscando:
Debería devolver todas las filas donde COLUMN contiene caracteres no ASCII (o caracteres ASCII no imprimibles como la nueva línea).
fuente
REGEXP
yRLIKE
funcionan de manera byte-byte, por lo que no son seguros para varios bytes y pueden producir resultados inesperados con conjuntos de caracteres de varios bytes. Además, estos operadores comparan los caracteres por sus valores de byte y los caracteres acentuados pueden no compararse como iguales, incluso si una colación dada los trata como iguales. "Un carácter que falta en los ejemplos de todos los anteriores es el carácter de terminación (\ 0). Esto es invisible para la salida de la consola MySQL y no puede ser detectado por ninguna de las consultas mencionadas anteriormente. La consulta para encontrarlo es simplemente:
fuente
Según la respuesta correcta, pero teniendo en cuenta también los caracteres de control ASCII, la solución que funcionó para mí es esta:
Hace lo mismo: busca violaciones del rango ASCII en una columna, pero también le permite buscar caracteres de control, ya que utiliza la notación hexadecimal para los puntos de código. Como no hay comparación o conversión (a diferencia de la respuesta de @ Ollie), esto también debería ser significativamente más rápido. (Especialmente si MySQL hace una terminación anticipada en la consulta de expresiones regulares, que definitivamente debería).
También evita la devolución de campos de longitud cero. Si desea una versión un poco más larga que funcione mejor, puede usar esto en su lugar:
Hace una verificación de longitud por separado para evitar resultados de longitud cero, sin considerarlos para un pase de expresiones regulares. Dependiendo del número de entradas de longitud cero que tenga, esto podría ser significativamente más rápido.
Tenga en cuenta que si su conjunto de caracteres predeterminado es algo extraño donde 0x00-0xFF no se asigna a los mismos valores que ASCII (¿existe tal conjunto de caracteres en algún lugar?), Esto devolvería un falso positivo. De lo contrario, disfruta!
fuente
REGEXP
está comprobando. Por lo tanto, se garantiza que siempre coincida. También^$
probablemente no es lo que quería.Intente usar esta consulta para buscar registros de caracteres especiales
fuente
La respuesta de @ zende fue la única que cubrió columnas con una mezcla de caracteres ascii y no ascii, pero también tenía esa problemática cuestión hexadecimal. Usé esto:
fuente
En Oracle podemos usar a continuación.
fuente
para esta pregunta también podemos usar este método:
Pregunta del zoológico sql:
encuentre todos los detalles del premio ganado por PETER GRÜNBERG
Caracteres no ASCII
ans: seleccione * de nobel donde el ganador como 'P% GR% _% berg';
fuente