• Publicidad

Uso del utf8

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

Uso del utf8

Notapor mariomb19 » 2012-05-21 07:53 @370

Buenas tardes, tengo una duda. Tengo datos que tienen acentos y al subirlos a la base de datos me sale este error.

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
DBD::Pg::st execute failed: ERROR:  invalid byte sequence for encoding "UTF8": 0xf36e2072 at /home/rocco/proyecto/retorno2.pl line 169, <$FH> line 1.

DBD::Pg::st execute failed: ERROR:  invalid byte sequence for encoding "UTF8": 0xf36e2072 at /home/rocco/proyecto/retorno2.pl line 169, <$FH> line 2.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


¿Qué módulo puedo usar para que me lea los acentos?

Muchas gracias...
mariomb19
Perlero nuevo
Perlero nuevo
 
Mensajes: 30
Registrado: 2012-04-30 09:39 @444

Publicidad

Re: Uso del utf8

Notapor explorer » 2012-05-21 09:43 @447

Antes, una pregunta...

¿Cómo prefieres guardar los datos de ese campo en la base de datos, como un array de bytes o como texto?

El mensaje de error dice que tienes definido el campo como de tipo texto, y el PostgreSQL, al leer lo que quieres grabar, se da cuenta de que no está bien codificado para la codificación por defecto del campo (UTF-8).

Caben varias opciones...
1.- Usa el módulo Encode para codificar correctamente hacia UTF-8 el texto que quieres guardar, o

2.- cambias la definición del campo, para que en vez de texto sea uno del tipo bytea (array de bytes)
$sth->bind_param($param_num, $bind_value, { pg_type => DBD::Pg::PG_BYTEA });
(así también)

3.- Después de la conexión con la base de datos, mandas una orden set client_encoding al valor en que los datos están codificados, y el servidor hará la conversión por ti, en la entrada y en la salida de los datos. Ver el capítulo 21.2 Soporte de conjuntos de caracteres, para más detalles.
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: Uso del utf8

Notapor mariomb19 » 2012-05-21 10:15 @468

Como texto, este es el campo que me da problemas:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
La cta. 6000050000 requiere una imputación relevante para la contab. de costes
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Así se ve en el txt, pero en Perl, así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
La cta. 6000050000 requiere una imputaci?n relevante para la contab. de costes.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

en el $arreglo[12] esta el dato así que le agregué.

$octets = encode("iso-8859-1",$arreglo[12]);

pero me sigue saliendo lo mismo.

Use el módulo Encode.
mariomb19
Perlero nuevo
Perlero nuevo
 
Mensajes: 30
Registrado: 2012-04-30 09:39 @444

Re: Uso del utf8

Notapor explorer » 2012-05-21 11:54 @537

A ver... el proceso es el siguiente: debes hacer un decode() desde la codificación en la que te viene el texto hacia el programa. Y luego hago un encode() hacia la codificación que me solicita la base de datos. O uso from_to(), que hace los dos pasos en uno.
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: Uso del utf8

Notapor mariomb19 » 2012-05-21 12:45 @573

Gracias, amigo. Este es el código pero no me sale el encode().

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -w
  2.  
  3. use Net::FTP;
  4. use File::chdir;
  5. use DBI;
  6. use DBD::Pg;
  7. use utf8;
  8. use Encode;
  9.  
  10.  
  11.  
  12. # variables globales usadas para localización de directorio y archivos
  13.  
  14. my $log1= "/home/rocco/hcm/log_retorno_error.txt";
  15. my $log2= "/home/rocco/proyecto/log_retorno_exitoso.txt";
  16. my $directorio_local="/home/rocco/hcm/";
  17. my $directorio_remoto="/";
  18. my $archivo_hcm="/home/rocco//proyecto/hcm.txt";
  19. my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
  20.  
  21. $year += 1900;
  22. $mon++;
  23. my $fecha= "$mday-$mon-$year $hour:$min:$sec\n";
  24.  
  25. my $regis="Inicio de conexión FTP:$fecha";
  26. my $regis2="Cierre correcto de la conexión FTP: $fecha";
  27. my $regis3="Inicio  correcto de la base datos: $fecha";  
  28. my $regis4="Cierre correcto de la base datos: $fecha";
  29. my $regis5="Insert exisotos a las base de datos tabla hcm: $fecha";                        
  30.    
  31.  
  32. # Abrimos el log
  33.  
  34. open my $LOG,">>$log1" or die "ERROR: No pude escribir en el log.txt: $!\n";
  35. open my $LOGG,">>$log2" or die "ERROR: No pude escribir en el log.txt: $!\n";
  36. my $username = "xxxxxxx";
  37. my $pwd = "xxxxxxx";
  38.  
  39. # Generando conexión con el servidor remoto
  40.                  
  41. exitoso ($regis);
  42.  
  43. my $ftp = Net::FTP->new("xxx.xxx.xxx.xxx");
  44. $ftp->login($username,$pwd);
  45. if (not defined $ftp)
  46. {
  47.      my $msl = "No se pude conectar al servidor: $fecha";
  48.      registra($msl);
  49.      die "$msl\n";
  50. }
  51.            
  52.      
  53.  
  54. # nos colocamos en el directorio donde dejaremos los archivos
  55. chdir "$directorio_local";  
  56.  
  57. # directorio en el servidor remoto
  58. $ftp->cwd("$directorio_remoto");              
  59.  
  60. # lista completa del directorio remoto
  61. my @linea_listado = $ftp->ls("/");
  62.  
  63. # Guardando mi lista en la variable listado
  64.  my $linea_listado="@linea_listado";
  65.        
  66. # Comenzando bucle para descartar archivos y extraer los necesarios
  67.        
  68. foreach $linea_listado(@linea_listado)
  69. {                          
  70.            if($linea_listado =~ m/(hcm\.txt$)/)
  71.            {
  72.                $ftp->get ("$linea_listado");
  73.                if (not defined $ftp)
  74.                {
  75.                        $msl ="filtrado de archivos fallo: $fecha ", $ftp->message;
  76.                        registra($msl);
  77.                        die "$msl\n";              
  78.                }
  79.                exitoso($linea_listado);
  80.                
  81.            }
  82.            
  83.  
  84. }
  85.        
  86. $ftp->quit;
  87. $msg="$regis2";
  88. exitoso($msg);
  89. $dirname = "$directorio_local";
  90. opendir ( DIR, $dirname );
  91.                    
  92. #Abriendo conexion a la base de datos
  93. my $dbh= DBI->connect('DBI:Pg:dbname=xxx;host=xxx.xxx.xxx.xxx','xxx','xxxxx');
  94. if ( not defined $dbh )
  95. {
  96.            $msl = "ERROR CONEXION A LA BASE DE DATOS : $fecha " . $DBI::errstr;
  97.            registra($msl);
  98.            die "$msl\n";          
  99. }
  100. my $msg="$regis3";
  101. exitoso($msg);
  102. #Seleccionando archivo hcm                        
  103. while (my $archivo = glob "$archivo_hcm")
  104. {
  105.            open my $RE, '<', $archivo;
  106.                                  
  107.            #Separando cada valor de los archivos y guardándolos en variables
  108.            while (my $linea = readline $RE)
  109.            {            
  110.                       my @cadena = split /\|\s*/, $linea;
  111.                        $cadena[7] = decode("iso-8859-1", my $octets);
  112.                       $octets = encode("iso-8859-1", $cadena[7]);
  113.                      
  114.                       #Aplicando el insert into
  115.                       $sth ="insert into conversion.conv_compensa_sap_fi(nu_acreedor,nu_doc_sap,nu_factura,nu_doc_comp,fe_factura,fe_pago,mt_factura,mt_sin_imp)
  116.                             values ('$cadena[0]','$cadena[1]','$cadena[2]','$cadena[3]','$cadena[4]','$cadena[5]','$cadena[6]','$octets')";
  117.  
  118.                       #Ejecutando query
  119.                       $subir= $dbh-> prepare($sth);                  
  120.                       $subir->execute();                                                    
  121.                       $subir->finish;
  122. }
  123.            #desconectando del bucle
  124.            close $RE;
  125. }          
  126. $msg="$regis5";
  127. exitoso($msg);                      
  128.  
  129. #Desconectándose de la base de datos
  130. $dbh->disconnect;
  131. $msg="$regis4";
  132. exitoso($msg);        
  133.                      
  134. #Cerrando el directorio local      
  135. closedir(DIR);
  136.  
  137.                      
  138. #Borrar archivos de compensación y rechazo del directorio local        
  139. $rootdir= "$directorio_local";
  140. chdir $rootdir;
  141. unlink <*.*>;
  142.                      
  143. close $LOG;
  144. exit 0;                    
  145. close $LOGG;
  146. exit 0;
  147.  
  148. # Subrutinas
  149. sub registra
  150. {
  151.            my $msl = shift;
  152.            print $LOG "$msl\n";
  153. }
  154. sub exitoso
  155. {
  156.            my $msg = shift;
  157.            print $LOGG "$msg\n";
  158. }      
  159.          
  160. print"exitoso";
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4


error:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Use of uninitialized value $octets in concatenation (.) or string at /home/rocco/proyecto/retorno2.pl line 162, <$FH> line 1.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
mariomb19
Perlero nuevo
Perlero nuevo
 
Mensajes: 30
Registrado: 2012-04-30 09:39 @444

Re: Uso del utf8

Notapor explorer » 2012-05-21 14:59 @666

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.                       $cadena[7] = decode("iso-8859-1", my $octets);
  2.                       $octets = encode("iso-8859-1", $cadena[7]);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Pero... ¿qué sentido tiene hacer eso?

Ahí estás diciendo que la codificación de entrada es la misma que la de salida... entonces, no te hace falta ninguna de estas líneas.

¿Realmente sabes la codificación de entrada y de salida de los datos?

El error dice que $octets, en la línea 111, está indefinido. Ahí debes poner la variable escalar que quieres decodificar.
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 3 invitados