Trouver et supprimer les caractères non ascii à partir d'un Oracle Varchar2
Nous sommes actuellement à la migration d'un de nos bases de données oracle en UTF8 et nous avons trouvé quelques enregistrements qui sont près de 4000 octets varchar limite.
Lorsque nous essayons de migrer ces dossier, ils échouent car ils contiennent des caractères qui deviennent multi-octets UF8 caractères.
Ce que je veux faire au sein de PL/SQL est de repérer ces personnages pour voir ce qu'ils sont, et ensuite, soit de les modifier ou de les supprimer.
Je voudrais faire :
SELECT REGEXP_REPLACE(COLUMN,'[^[:ascii:]],'')
mais l'Oracle ne pas mettre en œuvre les [:ascii:] classe de personnage.
Est-il un moyen simple de faire ce que je veux faire?
- Vous auriez probablement souhaitez remplacer
ç
parc
etcetera. Jeter l'ensemble du personnage est loin de pire que de jeter le signe diacritique. - Le 1er we besoin de savoir ce que les personnages sont avant de décider quoi faire avec eux.
Vous devez vous connecter pour publier un commentaire.
Dans un seul octet ASCII compatible encoding (par exemple, le Latin-1), les caractères ASCII sont simplement des octets dans la plage de 0 à 127. De sorte que vous pouvez utiliser quelque chose comme
[\x80-\xFF]
pour détecter les caractères non-ASCII.'['||chr(128)||'-'||chr(255)||']'
), 2.) essaie de remplacer tous les caractères dans'['||chr(32)||'-'||chr(127)||']'
résultats dans un ora-12728 erreur (plage non valide dans la regex). ma db charset est al32utf8. des idées?REGEXP_REPLACE ( 'abc', '['||chr(32)||'-'||chr(128)||']' , '_' )
produitabc
, tandis queREGEXP_REPLACE ( 'abc', '[^'||chr(32)||'-'||chr(128)||']' , '_' )
retourne___
).Si vous utilisez le
ASCIISTR
de la fonction de convertir le format Unicode pour les littéraux de la forme\nnnn
, vous pouvez ensuite utiliserREGEXP_REPLACE
de bande de ces littéraux, comme si......où les acteurs de terrain et de la table sont à votre domaine et les noms de table, respectivement.
ASCIISTR()
permettra de prolonger la chaîne au-delà de cette limite et la chaîne sera tronqué à 4000 caractères (perte de l'excès de caractères à partir de la fin). SQLFIDDLEwhere replace(asciistr(field),asciistr('\'),'\') <> field
Je pense que cela fera l'affaire:
'[\x80-\xFF]'
. Devrait être dans une réponse.regexp_replace(column, '[^ -~|[:space:]]', '')
Je ne le recommande pas pour la production de code, mais il a un sens et semble fonctionner:
Le select peut ressembler à l'exemple suivant:
Il y a probablement une façon plus directe, à l'aide d'expressions régulières. Avec un peu de chance, quelqu'un d'autre va le fournir. Mais voici ce que je ferais sans avoir besoin d'aller à l'manuels.
Créer un PLSQL fonction de recevoir votre chaîne d'entrée et de retour d'un varchar2.
Dans le PLSQL la fonction, faire un asciistr() de votre entrée. Le PLSQL est parce que peut retourner une chaîne de plus de 4000 et vous avez 32K disponibles pour varchar2 en PLSQL.
Cette fonction convertit les caractères non-ASCII \xxxx notation. Ainsi, vous pouvez utiliser des expressions régulières pour rechercher et supprimer ceux-ci. Puis retourner le résultat.
Suivantes fonctionne aussi:
J'ai eu un problème similaire et blogué à ce sujet ici.
J'ai commencé avec l'expression régulière pour alpha numériques, puis ajouté dans la base quelques caractères de ponctuation que j'ai aimé:
J'ai utilisé dump avec le 1016 variante de donner les caractères hexadécimaux je voulais remplacer qui je pourrais alors l'utilisateur dans un utl_raw.cast_to_varchar2.
J'ai trouvé la réponse ici:
http://www.squaredba.com/remove-non-ascii-characters-from-a-column-255.html
Puis exécutez la commande suivante pour mettre à jour vos données
Essayez ce qui suit:
Réponse donnée par Francisco Hayoz est le meilleur. N'utilisez pas de pl/sql fonctions si sql peut le faire pour vous.
Voici le test simple dans Oracle 11.2.03
Et "rep 127-255" est
Typ=1 Len=30: 226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
je.e pour certaines raisons, cette version d'Oracle ne pas remplacer char(226) et au-dessus.
L'utilisation de '['||chr(127)||'-'||chr(225)||']' donne le résultat souhaité.
Si vous avez besoin de remplacer d'autres personnages, de les ajouter à l'expression régulière ci-dessus ou utilisez remplacer imbriquée|regexp_replace si le remplacement est alors différent " (une chaîne vide).
Merci, cela a fonctionné pour mes fins. BTW il manque un guillemet simple dans l'exemple ci-dessus.
REGEXP_REPLACE (COLONNE,'[^' || CHR (32) || '-' || CHR (127) || ']', ' '))
Je l'ai utilisé dans word-wrap fonction. Parfois, il y a un intégré à NewLine/NL /CHR(10) /0A dans le texte entrants que c'était gâcher les choses.
Veuillez noter que lorsque vous utilisez
Oracle regexp, le moteur de match de certains caractères Latin-1 gamme: cela s'applique à tous les caractères qui ressemblent à des caractères ASCII comme Ä->A, Ö->O, Ü->U, etc., de sorte que [A-Z] n'est pas ce que vous connaissez d'autres environnements, comme, par exemple, Perl.
Au lieu de jongler avec les expressions régulières, essayez de changer pour le NVARCHAR2 type de données avant le jeu de caractères de mise à niveau.
Une autre approche: au lieu de couper une partie des champs " contenu vous pouvez essayer la fonction SOUNDEX, à condition que votre base de données contient des caractères Européens (c'est à dire en Latin-1) caractères seulement. Ou vous venez d'écrire une fonction qui convertit les caractères Latin-1 gamme de semblable à la recherche des caractères ASCII, comme
bien sûr uniquement pour les blocs de texte dépassant 4000 octets lorsqu'il est transformé en UTF-8.
Vous pouvez essayer quelque chose comme suite à la recherche de la colonne contenant des caractères non-ascii :
Ce faire, il faudra travailler.
Je suis un peu en retard pour répondre à cette question, mais a eu le même problème récemment (les gens couper et coller toutes sortes de choses dans une chaîne, et l'on ne sait pas toujours ce qu'il est).
Ce qui suit est un simple caractère de la liste blanche de l'approche:
DE edms_staging_table hne