web-dev-qa-db-fra.com

Comment trouver des caractères non-ASCII dans MySQL?

Je travaille avec une base de données MySQL qui contient des données importées de Excel . Les données contiennent des caractères non - ASCII (tirets, etc.) ainsi que des retours à la ligne ou des sauts de ligne masqués. Est-il possible de trouver ces enregistrements en utilisant MySQL?

104
Ed Mays

Cela dépend exactement de ce que vous définissez comme "ASCII", mais je suggérerais d'essayer une variante d'une requête comme celle-ci:

SELECT * FROM tableName WHERE columnToCheck NOT REGEXP '[A-Za-z0-9]';

Cette requête retournera toutes les lignes où columnToCheck contient des caractères non alphanumériques. Si vous avez d'autres caractères acceptables, ajoutez-les à la classe de caractères dans l'expression régulière. Par exemple, si les points, les virgules et les traits d'union sont corrects, modifiez la requête en:

SELECT * FROM tableName WHERE columnToCheck NOT REGEXP '[A-Za-z0-9.,-]';

La page la plus pertinente de la documentation MySQL est probablement 12.5.2 Expressions régulières.

54
Chad Birch

MySQL fournit une gestion complète des jeux de caractères qui peut vous aider à résoudre ce type de problème.

SELECT whatever
  FROM tableName 
 WHERE columnToCheck <> CONVERT(columnToCheck USING ASCII)

La fonction CONVERT(col USING charset) transforme les caractères non convertibles en caractères de remplacement. Ensuite, le texte converti et non converti sera différent.

Voir ceci pour plus de discussion. http://dev.mysql.com/doc/refman/5.7/en/charset-repertoire.html

Vous pouvez utiliser n'importe quel nom de jeu de caractères à la place d'ASCII. Par exemple, si vous voulez savoir quels caractères ne seront pas restitués correctement dans la page de code 1257 (lituanien, letton, estonien), utilisez CONVERT(columnToCheck USING cp1257)

183
O. Jones

Vous pouvez définir ASCII comme tous les caractères ayant une valeur décimale de 0 à 127 (0x00 à 0x7F) et rechercher des colonnes avec des caractères non-ASCII à l'aide de la requête suivante

SELECT * FROM TABLE WHERE NOT HEX(COLUMN) REGEXP '^([0-7][0-9A-F])*$';

C’était la question la plus complète que je pouvais trouver.

91
zende

C'est probablement ce que vous recherchez:

select * from TABLE where COLUMN regexp '[^ -~]';

Il doit renvoyer toutes les lignes où COLUMN contient des caractères non-ASCII (ou des caractères ASCII non imprimables, tels que nouvelle ligne).

41
David Minor

Le caractère de fin (\ 0) est l'un des caractères manquants parmi tous les exemples ci-dessus. Ceci est invisible pour la sortie de la console MySQL et ne peut être découvert par aucune des requêtes mentionnées précédemment. La requête pour le trouver est simplement:

select * from TABLE where COLUMN like '%\0%';
13
Rob Bailey

Sur la base de la réponse correcte, mais en prenant également en compte les caractères de contrôle ASCII, la solution qui a fonctionné pour moi est la suivante:

SELECT * FROM `table` WHERE NOT `field` REGEXP  "[\\x00-\\xFF]|^$";

Il fait la même chose: recherche les violations de la plage ASCII dans une colonne, mais vous permet également de rechercher des caractères de contrôle, car il utilise la notation hexadécimale pour les points de code. Comme il n'y a pas de comparaison ou de conversion (contrairement à la réponse de @ Ollie), cela devrait aussi être beaucoup plus rapide. (Surtout si MySQL effectue une terminaison précoce sur la requête regex, ce qu'il devrait absolument faire.)

Cela évite également de renvoyer des champs de longueur nulle. Si vous voulez une version légèrement plus longue et plus performante, vous pouvez utiliser ceci à la place:

SELECT * FROM `table` WHERE `field` <> "" AND NOT `field` REGEXP  "[\\x00-\\xFF]";

Il effectue une vérification séparée de la longueur pour éviter des résultats nuls, sans les prendre en compte pour un regex. En fonction du nombre d'entrées de longueur nulle que vous avez, cela pourrait être considérablement plus rapide.

Notez que si votre jeu de caractères par défaut est bizarre et que 0x00-0xFF ne correspond pas aux mêmes valeurs que ASCII (existe-t-il un tel jeu de caractères?), Le résultat serait un faux positif. Sinon, profitez-en!

2
Mahmoud Al-Qudsi

Dans Oracle, nous pouvons utiliser ci-dessous.

SELECT * FROM TABLE_A WHERE ASCIISTR(COLUMN_A) <> COLUMN_A;
0
Malaka Gunawardhana

Essayez d'utiliser cette requête pour rechercher des enregistrements de caractères spéciaux

SELECT *
FROM tableName
WHERE fieldName REGEXP '[^a-zA-Z0-9@:. \'\-`,\&]'
0
Sachin

La réponse de @ zende était la seule qui couvrait les colonnes avec un mélange de caractères ascii et non ascii, mais il y avait aussi ce problème problématique. J'ai utilisé ceci:

SELECT * FROM `table` WHERE NOT `column` REGEXP '^[ -~]+$' AND `column` !=''
0
chiliNUT