martes, 30 de junio de 2009

Oracle, length problem with special characters in VARCHAR2

Oracle maneja de distintas formas la comprobación del tamaño maximo para una columna dependiendo del charset de la BD.
En nuestro caso lo teniamos definido como UTF8 y se nos presentaba el siguiente problema:

Problema:
Si el maximo para una columna es de 10 y dentro de los 10 caracteres habia alguno con acento o ñ a la hora de insertar obteniamos el siguiente error:

ORA-12899: value too large for column

Ejemplo:

CREATE TABLE TEST (
COL_A VARCHAR2(2) NOT NULL
);


INSERT INTO TEST2 VALUES ('aa')
OK
INSERT INTO TEST2 VALUES ('áá')
ERROR


Solució:
Realmente el maximo que indicamos por defecto es en bytes y al tener charset UTF8 esta tomando "á" como 2 bytes.

Opción A: Cambiar el charset de la BD.

Opción B: Modificar todas las columnas de tipo VARCHAR2 para que interpreten su maximo como caracteres y no como bytes.

Ejemplo:

CREATE TABLE TEST (
COL_A VARCHAR2(2 CHAR) NOT NULL
);


INSERT INTO TEST2 VALUES ('aa')
OK
INSERT INTO TEST2 VALUES ('áá')
OK


Para implementar esta alternativa de forma automatica he creado el siguiente scritp:

select 'ALTER TABLE ' || table_name || ' MODIFY ( ' || column_name ||' '|| data_type || ' ( '|| char_length || ' CHAR));'
from cols
where data_type = 'VARCHAR2'
and char_used = 'B'

Esto nos genera una lista con todas las consultas que debemos ejecutar para implementar el cambio.

3 comentarios:

Anónimo dijo...

gracias!

Pedro dijo...

Muchas gracias por el aporte.

Ha sido de gran utilidad

Ariel dijo...


Excelente, muy util la explicacion, a mi personalmente me arrojo el error:

ORA-06502: PL/SQL: numeric or value error: character to number conversion error

Gracias !