Algo más sobre los conjuntos de caracteres

2 comentarios

Lo básico sobre los conjuntos de caracteres ya habíamos visto en este artículo:

Entendiendo a los conjuntos de caracteres

Y ahora haremos un repaso sobre ellos, que puede ser importante conocer:

  •  El conjunto de caracteres original, sobre el cual están basados todos los demás es el ASCII
  • El ASCII funciona perfectamente con el idioma inglés pero no sirve para los demás idiomas ya que no tiene vocales acentuadas ni vocales con diéresis ni eñes ni otros caracteres que se usan en otros idiomas
  • En un conjunto de caracteres se le asigna un número a cada carácter
  • En el ASCII esos números van desde el 0 hasta el 127. Dentro de esos 128 caracteres hay 32 que son invisibles y sirven para control (tecla ENTER, tecla TAB, tecla ESC, etc.)
  • Los números desde el 128 hasta el 255 están libres y pueden ser usados por otros conjuntos de caracteres
  • Un ejemplo son los llamados ISO8859 que están muy difundidos. Hay varias versiones, cada una de esas versiones usa los 128 caracteres sobrantes en su propia manera. Los caracteres desde el 128 hasta el 159 no están asignados y pueden ser usados para caracteres de control. Los caracteres adicionales que necesitan los distintos idiomas (español, portugués, francés, alemán, polaco, serbio, ruso, etc.) se codifican desde el 160 hasta el 255
  • El conjunto de caracteres ISO8859_1 tiene todos los caracteres de los idiomas europeos occidentales. Es el más ampliamente usado de los ISO8859 ya que permite escribir en: afrikaans, albanés, alemán, catalán, danés, escocés, español, finés, francés, holandés, inglés, islandés, italiano, noruego, portugués, rumano, suaheli, sueco, vasco
  • El conjunto de caracteres ISO8859_2 tiene todos los caracteres de los idiomas europeos centrales: checo, eslovaco, esloveno, polaco, etc.
  • Hay varios ISO8859 más, cada uno de ellos conteniendo los caracteres necesarios para escribir en distintos idiomas europeos
  • Los idiomas del este de Asia no pueden ser codificados con un solo byte ya que esos idiomas tienen muchos miles de caracteres, llamados ideogramas, y en un byte como máximo se pueden tener 256 caracteres. Por ese motivo se necesita de más de un byte para codificarlos
  • Esto implica que la cantidad de caracteres visibles es distinta a la cantidad de bytes necesarios para almacenarlos. En ASCII y en ISO8859 cada carácter ocupa exactamente un byte. En los idiomas de Asia oriental eso no es cierto, ya que cada carácter ocupa varios bytes.
  • Para unificar a todos los conjuntos de caracteres y evitar tantas incompatibilidades se inventó el UNICODE
  • Dentro de UNICODE hay tres posibilidades: UTF-8, UTF-16, UTF-32
  • Con UNICODE se pueden codificar hasta 1.114.112 caracteres distintos, pero la mayoría de ellos aún no están codificados
  • Como se pueden usar hasta 4 bytes por cada carácter lo más sencillo hubiera sido hacer eso, pero el espacio de almacenamiento sería muy grande, ya que para tener todos los caracteres usados por los lenguajes europeos con 2 bytes sería más que suficiente. Es por eso que se inventaron varias formas de codificación, las cuales empiezan con las siglas UTF. Las más usada es la UTF-8
  • Cuando se crea una Base de Datos se puede especificar cual conjunto de caracteres se usará por defecto en ella
  • Si todo el texto que será introducido en las columnas de tipo CHAR o VARCHAR estará escrito en alguno de los idiomas europeos occidentales (el español, entre ellos) usar ISO8859_1. Si existe la posibilidad de que estén escritos en otros idiomas europeos (checo, polaco, ruso, etc.) usar UTF-8.
  • Hasta la versión 2.5.3 el Firebird no dispone de la posibilidad de cambiar el conjunto de caracteres de una Base de Datos. Hay programas utilitarios como el IBEScript que sí tienen esa opción. Con Firebird 3.0 ya se podrá cambiar el conjunto de caracteres

Artículos relacionados:

Entendiendo a los conjuntos de caracteres

Funciones útiles con los conjuntos de caracteres

El índice del blog Firebird21

El foro del blog Firebird21

 

Anuncios

Eliminando códigos de control en las cadenas alfanuméricas

4 comentarios

Como seguramente sabes, todos los caracteres que usas para escribir textos con la computadora tienen un código ASCII. Así por ejemplo el código ASCII de la letra A mayúscula es 65, el código ASCII del dígito 0 es 48, etc.

Los códigos ASCII cuyos valores van desde al 0 al 31 en su mayoría no son imprimibles y se llaman “códigos de control”.

Si una columna CHAR o VARCHAR tiene códigos de control entonces el resultado que obtendrás al ejecutar un SELECT o al utilizar funciones alfanuméricas tales como LEFT(), TRIM(), etc. podría no ser el esperado.

Entenderemos mejor el problema con el siguiente ejemplo.

Tenemos una tabla llamada PRODUCTOS la cual tiene las siguientes filas:

ASCII1

Captura 1. Si haces clic en la imagen la verás más grande

Ahora, reemplazamos todos los espacios en blanco por el código de control 0 (cero):

UPDATE
   PRODUCTOS
SET
   PRD_NOMBRE = REPLACE(PRD_NOMBRE, ' ', ASCII_CHAR(0))

Volvemos a consultar el contenido de la tabla PRODUCTOS y ahora esto es lo que obtenemos:

ASCII2

Captura 2. Si haces clic en la imagen la verás más grande

¿Qué pasó aquí? ¡¡¡Desaparecieron todos los caracteres que se encontraban después del primer espacio en blanco!!!

Pues no, no te asustes, no han desaparecido sino que no son visibles. Cuando el Firebird encuentra un caracter cuyo código ASCII es cero ya no muestra los siguientes caracteres, llega solamente hasta el que tiene código ASCII cero.

Entonces, si ahora actualizamos nuestra tabla PRODUCTOS de forma inversa (o sea, reemplazando los códigos ASCII cero con espacios en blanco):

UPDATE
   PRODUCTOS
SET
   PRD_NOMBRE = REPLACE(PRD_NOMBRE, ASCII_CHAR(0), ' ')

esto será lo que obtendremos:

ASCII1

Captura 3. Si haces clic en la imagen la verás más grande

¡¡¡Voilá!!! ¡¡¡Reaparecieron todos los caracteres faltantes!!!

Conclusión:

Si al consultar el contenido de una columna alfanumérica notas que faltan caracteres o que el comportamiento de las funciones alfanuméricas LEFT(), RIGHT(), TRIM(), etc., es extraño entonces es posible que la causa sea que hay caracteres de control en esa columna. Puedes utilizar la función REPLACE() para reemplazar a esos caracteres de control por otros caracteres, típicamente por espacios en blanco, como has visto en los ejemplos anteriores y de esa manera solucionarás el problema.

Artículo relacionado:

El índice del blog Firebird21

ASCII_CHAR()

1 comentario

Descripción: Devuelve el caracter ASCII correspondiente a su argumento

Tipo de resultado: [VAR]CHAR(1) CHARACTER SET NONE

Sintaxis:

ASCII_CHAR(número)

   número: un entero en el rango de 0..255

IMPORTANTE: Si la función externa ASCII_CHAR() está declarada en tu Base de Datos, ella tendrá preferencia. Para que la función interna pueda usarse deberás borrar (DROP) o cambiar (ALTER) a la función externa.

.