Je travaille avec une base de données MySQL qui contient des données importées d' Excel . Les données contiennent des caractères non ASCII (tirets em, etc.) ainsi que des retours chariot masqués ou des sauts de ligne. Existe-t-il un moyen de trouver ces enregistrements en utilisant MySQL?
mysql
character-encoding
Ed Mays
la source
la source
Réponses:
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:
Cette requête renverra 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 de l'expression régulière. Par exemple, si les points, les virgules et les traits d'union sont corrects, remplacez la requête par:
La page la plus pertinente de la documentation MySQL est probablement 12.5.2 Expressions régulières .
la source
SELECT * FROM tbl WHERE colname NOT REGEXP '^[A-Za-z0-9\.,@&\(\) \-]*$';
MySQL fournit une gestion complète des jeux de caractères qui peut aider à résoudre ce genre de problème.
La
CONVERT(col USING charset)
fonction transforme les caractères non convertibles en caractères de remplacement. Ensuite, le texte converti et non converti sera inégal.Voir ceci pour plus de discussion. https://dev.mysql.com/doc/refman/8.0/en/charset-repertoire.html
Vous pouvez utiliser n'importe quel nom de jeu de caractères que vous souhaitez à la place de ASCII. Par exemple, si vous voulez savoir quels caractères ne s'afficheront pas correctement dans la page de codes 1257 (lituanien, letton, estonien), utilisez
CONVERT(columnToCheck USING cp1257)
la source
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
C'était la requête la plus complète que je puisse proposer.
la source
SELECT * FROM table WHERE LENGTH( column ) != CHAR_LENGTH( column )
'ā'
(encodée par la séquence d'octets0x0101
) - elle serait réputée "ASCII" en utilisant ce test: un faux négatif ; en effet, certains jeux de caractères ne codent pas les caractères ASCII à l'intérieur0x00
de0x7f
sorte que cette solution donnerait un faux positif. NE VOUS FIEZ PAS À CETTE RÉPONSE!LENGTH(column)
seront donc un multiple constantCHAR_LENGTH(column)
quelle que soit la valeur.C'est probablement ce que vous recherchez:
Il doit renvoyer toutes les lignes où COLUMN contient des caractères non ASCII (ou des caractères ASCII non imprimables tels que le saut de ligne).
la source
REGEXP
etRLIKE
fonctionnent par octet, ils ne sont donc pas sécurisés sur plusieurs octets et peuvent produire des résultats inattendus avec des jeux de caractères multi-octets. En outre, ces opérateurs comparent les caractères par leurs valeurs d'octets et les caractères accentués peuvent ne pas être comparables même si un classement donné les traite comme égaux. "Un caractère manquant dans tous les exemples ci-dessus est le caractère de fin (\ 0). Ceci est invisible pour la sortie de la console MySQL et ne peut être découvert par aucune des requêtes mentionnées ci-dessus. La requête pour le trouver est simplement:
la source
Sur la base de la bonne réponse, mais en tenant également compte des caractères de contrôle ASCII, la solution qui a fonctionné pour moi est la suivante:
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 également être beaucoup plus rapide. (Surtout si MySQL effectue une résiliation anticipée de la requête regex, ce qu'il devrait certainement.)
Cela évite également de renvoyer des champs de longueur nulle. Si vous voulez une version légèrement plus longue qui pourrait fonctionner mieux, vous pouvez utiliser ceci à la place:
Il effectue une vérification séparée de la longueur pour éviter les résultats de longueur nulle, sans les considérer pour une passe d'expression régulière. Selon le nombre d'entrées de longueur nulle que vous avez, cela pourrait être beaucoup plus rapide.
Notez que si votre jeu de caractères par défaut est quelque chose de bizarre où 0x00-0xFF ne correspond pas aux mêmes valeurs que ASCII (existe-t-il un tel jeu de caractères quelque part?), Cela renverrait un faux positif. Sinon, profitez-en!
la source
REGEXP
est la vérification. Par conséquent, il est garanti de toujours correspondre. Ce^$
n'est probablement pas non plus ce que vous vouliez.Essayez d'utiliser cette requête pour rechercher des enregistrements de caractères spéciaux
la source
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 hexadécimal. J'ai utilisé ceci:
la source
Dans Oracle, nous pouvons utiliser ci-dessous.
la source
pour cette question, nous pouvons également utiliser cette méthode:
Question de sql zoo:
Retrouvez tous les détails du prix remporté par PETER GRÜNBERG
Caractères non ASCII
ans: sélectionnez * de nobel où gagnant comme «P% GR% _% berg»;
la source