Actualmente estamos migrando una de nuestras bases de datos oracle a UTF8 y hemos encontrado algunos registros que están cerca del límite varchar de 4000 bytes. Cuando intentamos migrar estos registros fallan ya que contienen caracteres que se convierten en caracteres UF8 multibyte. Lo que quiero hacer con PL/SQL es localizar estos caracteres para ver cuáles son y luego cambiarlos o eliminarlos.
Me gustaría hacer:
SELECT REGEXP_REPLACE(COLUMN,'[^[:ascii:]],'')
pero Oracle no implementa la clase de caracteres [:ascii:].
¿Hay alguna forma sencilla de hacer lo que quiero?
En una codificación compatible con ASCII de byte único (por ejemplo, Latin-1), los caracteres ASCII son simplemente bytes en el rango de 0 a 127. Por tanto, puede utilizar algo como [\x80-\xFF]
para detectar caracteres no ASCII. Así que puedes usar algo como [\x80-\xFF]
para detectar caracteres no ASCII.
Probablemente exista una forma más directa utilizando expresiones regulares. Con suerte, alguien la proporcionará. Pero esto es lo que yo haría sin necesidad de ir a los manuales.
Crear una función PLSQL para recibir su cadena de entrada y devolver un varchar2.
En la función PLSQL, haga un asciistr() de su entrada. El PLSQL es porque eso puede devolver una cadena más larga que 4000 y usted tiene 32K disponibles para varchar2 en PLSQL.
Esa función convierte los caracteres no ASCII a notación \xxxx. Así que usted puede utilizar expresiones regulares para encontrar y eliminar los. Luego devuelve el resultado.
Tuve un problema similar y lo publiqué en mi blog aquí. Empecé con la expresión regular para números alfa y luego añadí los pocos caracteres de puntuación básicos que me gustaban:
select dump(a,1016), a, b
from
(select regexp_replace(COLUMN,'[[:alnum:]/''%()> -.:=;[]','') a,
COLUMN b
from TABLE)
where a is not null
order by a;
Utilicé dump con la variante 1016 para obtener los caracteres hexadecimales que quería reemplazar y que luego pude utilizar en un utl_raw.cast_to_varchar2.