• Publicidad

Codificación de datos en base de datos Oracle

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Codificación de datos en base de datos Oracle

Notapor keparodo » 2012-06-22 16:05 @712

Hola,
tengo un problema, nuevamente...

Base de datos Oracle, una tabla, un select, siguiente resultado:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
lugar           abrev
----------------------
HUALPEN         THN
HUALPéN      CCH
HUALPÿƿÿ©N  CCH
HUALPÈN                CCH
HUALPÉN                CCH
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


hago este select y lo pongo en un hash, mi llave es lugar

my %arr_lugar=();
... ...
foreach $registro (@$data_sql){ # recorre los registros a procesar
$arr_lugar{$registro->[0]} = $registro->[1];
}

al recorrer el hash y desplegar la información almacenada, el resultado es el siguiente:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
lugar           abrev
-----------------------
HUALPEN         THN
HUALP??N        CCH
HUALP??????A?N  CCH
HUALPEN         CCH
HUALPEN         CCH
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


y, al buscar arr_lugar{HUALPEN} me arroja CCH cuando debió ser THN, pues era la unica que en la BD estaba escrita igual...

Gracias.
keparodo
Perlero nuevo
Perlero nuevo
 
Mensajes: 21
Registrado: 2011-12-14 17:17 @762

Publicidad

Re: Codificación de datos en base de datos Oracle

Notapor explorer » 2012-06-22 20:04 @877

Pero... ¿en qué codificación están los datos de la base de datos?

Te recomiendo un vistazo al hilo 44 recetas para trabajar con Unicode en Perl. Algo parecido a lo que quieres hacer está en la receta 42 (tercera página).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Codificación de datos en base de datos Oracle

Notapor keparodo » 2012-06-26 17:51 @786

según la instrucción:
Sintáxis: [ Descargar ] [ Ocultar ]
Using sql Syntax Highlighting
  1. SELECT * FROM nls_database_parameters WHERE parameter='NLS_CHARACTERSET';
  2.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


la codificación es: WE8ISO8859P1 --> iso-8859-1
keparodo
Perlero nuevo
Perlero nuevo
 
Mensajes: 21
Registrado: 2011-12-14 17:17 @762

Re: Codificación de datos en base de datos Oracle

Notapor explorer » 2012-06-26 18:52 @828

Pues vaya... según el contenido que mostrabas en el primer mensaje, hubiera dicho que era codificación utf8...

Es más, yo haría la prueba de pasar los datos leídos por el Encode, intentando leerlos en utf8, y sacarlos en pantalla (indicando a su vez, al STDOUT, la codificación de nuestra terminal).

Mira:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2. use v5.14;
  3. my $textoraro = 'HUALPéN';
  4. say $textoraro;              # sale HUALPéN, en una terminal utf8
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Lo que me descuadra es el 'HUALPÿƿÿ©N' y los dos siguientes... podría ser que estuviera codificado en Han... o que hubiera ocurrido en error múltiple de codificación en cascada.

Los dos últimos ejemplos sí que parecen que estén en iso-8859-1 (suponiendo que nos has copiado la salida desde una terminal iso-8859-1...)
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Codificación de datos en base de datos Oracle

Notapor keparodo » 2012-06-27 13:52 @619

¿Y cómo sé en lo que está escribiendo y leyendo Perl?

no entiendo...

por que es que en la tabla veo un valor y perl me lo deja en otro al escribirlo en un %arreglo?
es sólo codificación en perl?
no bastaría con escribir esa salida en lo mismo que esta en la bd?
keparodo
Perlero nuevo
Perlero nuevo
 
Mensajes: 21
Registrado: 2011-12-14 17:17 @762

Re: Codificación de datos en base de datos Oracle

Notapor explorer » 2012-06-27 17:37 @775

Perl, por defecto, lee y escribe en ISO-8859-1.

A partir de ahí, todo lo que entre que no sea esa codificación, debería ser decodificada. Y lo mismo para la salida.

Vuelvo a recomendarte la lectura de las 44 recetas para trabajar con Unicode en Perl. Las primeras serán muy clarificadoras.

En el reciente libro Modern Perl (en inglés) hay un apartado que explica cómo gestiona Perl las distintas codificaciones en las variables escalares, sino se indica cuáles debe usar (algo que no debe hacerse, desde luego).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Codificación de datos en base de datos Oracle

Notapor keparodo » 2012-06-28 11:03 @502

Sí, lo hice, realicé varias pruebas, pero ninguna me arroja como resultado el valor real que hay en la tabla... :cry:
keparodo
Perlero nuevo
Perlero nuevo
 
Mensajes: 21
Registrado: 2011-12-14 17:17 @762

Re: Codificación de datos en base de datos Oracle

Notapor explorer » 2012-06-28 12:52 @578

Por defecto, Perl no hace ninguna transformación a los datos que recibe de una base de datos. Solo a la entrada y salida del programa.

Entonces, si quieres saber qué es lo que hay en celda, te vale con leer el contenido de la base de datos y mandarlos imprimir tal cual. Como Perl trabaja en iso-8859-1 (latin1) por defecto, no aplicará ninguna traducción de caracteres.

La salida, la entubas a una herramienta que te permita ver el contenido real de lo que sale, porque, recuerda: tu terminal de línea de comandos trabaja con una determinada codificación, así que lo que quizás estás viendo no es lo que realmente está saliendo en pantalla.

Por ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
$ ./consulta_DB.pl explorer |hexdump -C
00000000  45 73 74 6f 20 65 73 20  75 6e 61 20 70 72 75 65  |Esto es una prue|
00000010  62 61 20 64 65 20 75 63  73 32 2e 20 c3 a1 c3 a9  |ba de ucs2. ....|
00000020  c3 ad c3 b3 c3 ba c3 b1  c3 91 0a                 |...........|
0000002b
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

De esta manera, sí que vemos el contenido real. Si algún carácter está tildado, lo veremos repartido entre uno y cuatro bytes (según la codificación). Y tendremos más pistas de qué es lo que estamos manejando. En concreto, este ejemplo muestra pares de bytes comenzando con 'c3', así que es posible que está en utf-8. Si lo saco en la pantalla en una terminal con codificación utf8, sale bien:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
$ ./consulta_DB.pl explorer
Esto es una prueba de ucs2. áéíóúñÑ
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Así que ya ves, debes tener en cuenta:
  • la codificación que usa Perl en la salida (sabemos que es latin1, pero no nos influye, de momento)
  • la codificación de los datos (que no lo sabemos)
  • la codificación de la terminal en la que estás trabajando (tampoco la sabemos).
Hoy en día, la mayor parte de las terminales funcionan en utf8 (así trabajo yo en Linux desde hace años). Y entonces es un problema trabajar con Perl porque sabemos que todo lo hace en latin1. Hay que acordarse siempre de, que si tengo datos en utf8, acomodar la salida.

Si tengo este programa:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2. print "[áéíóúñÑ]\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
que he escrito en una terminal utf8 y con un editor de textos que entiende utf8, la salida parece que es correcta:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
$ ./kk.pl
[áéíóúñÑ]
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
pero solo es aparente... resulta que Perl está sacando una ristra de bytes que, al salir por la terminal, ésta los interpreta siempre como si estuvieran en utf8, y nos muestra los caracteres correctos. Pero porque a Perl no le hemos dicho cómo hemos escrito esos caracteres, solo está almacenando una ristra de bytes. Y como trabaja por defecto en latin1, no realiza ningún cambio en ellos.

Si le doy más información al programa:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2. use utf8;
  3. print "[áéíóúñÑ]\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
con el pragma 'use utf8;' estamos indicando que, realmente, estamos escribiendo el programa con caracteres codificados en utf8. La salida es complicada:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
$ ./kk.pl
[�������]
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
(caracteres en utf8 que indican error de codificación). Si le pedimos ayuda a hexdump, ya sabemos qué pasa:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
$ ./kk.pl|hexdump -C
00000000  5b e1 e9 ed f3 fa f1 d1  5d 0a                    |[.......].|
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
Perl, al saber que el programa está codificado en utf8, sabe cómo traducir las cadenas de caracteres que se encuentra dentro de él. Al encontrar caracteres tildados, los transforma todos a caracteres Unicode (realmente, traduce todos los textos a Unicode). A la hora de la salida, como por defecto es en latin1, hace la traducción de Unicode a latin1, y eso es justo lo que estamos viendo: caracteres codificados en latin1.

La solución es indicarle a Perl que, además, la salida estándar debe ir también en utf8, porque así es como está funcionando la terminal:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2. use utf8;
  3. use open qw(:utf8 :std);
  4. print "[áéíóúñÑ]\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Y ya sale correcto. También hubiese valido con "use open ':locale';", ya que entonces Perl tomaría los valores de codificación de las variables de entorno de mi sistema. De esta manera, puedo mover el programa entre distintos sistemas y codificaciones.

¡Bienvenido al mundo de la torre de Babel!
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 14 invitados