Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 13-09-2022
novato_erick novato_erick is offline
Miembro
 
Registrado: ago 2010
Ubicación: Panamá
Posts: 396
Poder: 14
novato_erick Va por buen camino
charset ASCII a UTF8 Firebird

Hola Chicos que tal?

Hace apenas 22 días he notado un comportamiento despues de usar las versiones de Firebird 2.x sin ningún problema despues de casi 10 años no habia tenido la necesidad de migrar pero ultimamente con 22 conexiones simultaneas me ah estado bloqueando las transacciones y buscando el mensaje de error en los log de Firebird aparece la sugerencia que ese problema se da en las versiones 2.5.x

Cita:
SERVERFERRE (Client) Thu Sep 01 12:38:45 2022
REMOTE INTERFACE/gds__detach: Unsuccesful detach from database.
Uncommitted work may have been lost

SERVERFERRE (Server) Thu Sep 01 12:39:35 2022
Shutting down the server with 22 active connection(s) to 1 database(s), 1 active service(s)


SERVERFERRE (Client) Thu Sep 01 12:39:42 2022
Guardian starting: "C:\Program Files (x86)\Firebird\Firebird_2_5\bin\fbserver.exe"
A la hora de realizar respaldo para luego actualizar usando GBAK a 3.0
manda estos errores:

gbak:restore failed for record in table PROVEEDORES
Error: gbak: ERROR:Malformed string
gbak:Invalid data detected. Use -FIX_FSS_DATA option.

trate de corregirlo usando: -FIX_FSS_DATA ASCII -FIX_FSS_METADATA ASCII pues en teoría está la Base de datos en ASCII.
Cita:
C:\Program Files (x86)\Firebird\Firebird_3_0>gbak -r o -v -p 16384 -user SYSDBA -password masterkey -FIX_FSS_DATA ASCII -FIX_FSS_METADATA ASCII "C:\EDD MIPROGRAMA\BDASCII.FBK" "C:\EDD MIPROGRAMA\BDASCII.FDB"
en fin mi programa obvianmente la estructura de la DB está hace 15 años más o menos casi nunca toco la DB pero a estas altura en base a la experiencia de ustedes me recomendaría pasar a UTF8 y ¿cual sería el mejor medio?

Saludos;

novato_erick
Responder Con Cita
  #2  
Antiguo 13-09-2022
novato_erick novato_erick is offline
Miembro
 
Registrado: ago 2010
Ubicación: Panamá
Posts: 396
Poder: 14
novato_erick Va por buen camino
Bueno leyendo las ayuda que aquí mismo la comunidad del Club encontré este post por el amigo Casimiro de hace buen tiempo: https://clubdelphi.com/foros/showthread.php?t=90783
la cual creo que dejaría a un lado el UTF8.

aún mi pregunta de la recomendación está en pié para que alguien me responda.

Saludos nuevamente;

novato_erick
Responder Con Cita
  #3  
Antiguo 13-09-2022
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Yo hace un tiempo migré la base de datos a UNICODE.
La base de datos tenía el charset NONE, por lo que admitía cualquier cosa que le pusieras y no hacía ninguna transformación.
Cuando empecé a entrar y leer datos desde diferentes sistemas empezaron a generarse muchos conflictos:
Desde la web se metía texto en formato UTF-8 y desde Windows se leia como WIN-1252. Lo mismo sucedía cuando se escribía en windows y se leia en la web.

La solución:
Poner los campos texto (CHAR, VARCHAR, BLOB tipo texto) a charset UNICODE.
Luego en la conexión a la base de datos le dices qué charset utilizas y entre el cliente y el servidor hacen la transformación necesaria.

Nota:
Yo trabajo con un Delphi viejo (Delphi 6) por lo que no adminte UTF8 como Charset.

Ejemplo:
Código SQL [-]
-- Definicion de campo de texto con CHARST UNICODE
CREATE DOMAIN DESCRIPCIONES AS  VARCHAR(256) CHARACTER SET UNICODE_FSS 
DEFAULT '' 
NOT NULL 
COLLATE UNICODE_FSS
Código Delphi [-]
  // Conexión a la base de datos indicando el Charset con el que quiero leer los datos
  with DataBase do
  begin
     try
        // Probamos conexion
        if not TestConnected then
        begin
           DBName := Entorno.BaseDeDatos;
           DBParams.Clear;
           DBParams.Values['user_name'] := Entorno.UsuarioBD;
           DBParams.Values['password'] := Entorno.ClaveBD;

           // El charset de la conexion: Normalmente en Windows en castellano WIN1252
           if (Entorno.CharsetBD <> '') then
              DBParams.Values['lc_ctype'] := Entorno.CharsetBD;

           if (Entorno.RolBD <> '') then
              DBParams.Values['sql_role_name'] := Entorno.RolBD;
           Log(format('Conectando. user_name: %s, password: %s, sql_role_name: %s', [DBParams.Values['user_name'], DBParams.Values['password'], DBParams.Values['sql_role_name']]));
           Open;
        end;
     except
        on e: Exception do
        begin
           try
              if (Assigned(FLogo)) then
                 FLogo.Hide;
           except
           end;
           ShowMessage(Format(_('Imposible abrir %s' + #13#10 + 'user_name: %s, sql_role_name: %s.') + #13#10 + e.Message, [Entorno.BaseDeDatos, Entorno.UsuarioBD, Entorno.RolBD]));
        end;
     end;
  end;
Responder Con Cita
  #4  
Antiguo 13-09-2022
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Para migrar la base de datos me hice una pequeña aplicación que leia la estructura de la base de datos y crea otra modificando los campos "texto" para agregarles el CHARSET (CHARACTER SET UNICODE_FSS).

UNICODE es el sistema para identificar a cada caracter (cientos de miles en este momento).
UTF-8 es una forma de codificar UNICODE tratando de reducir el espacio necesario.
UTF-16, UTF-32: Lo mismo que UTF-8 pero sacrificando espacio.
WIN1250, WIND1251, WIN1252, ISO8859, etc.: Son mapas de caracteres. Solo contienen algunos. Por ejemplo la Ñ está en algunos juegos de caracteres y en otros, la posición de ese carater representa otro distinto.
ASCII: Es el juego mas limitado de 256 caracteres.
NONE: En Firebird, se refiere a que tomará los bytes que se le pase y los guardará sin interpretar dentro del campo de texto. A quien lea también se le enviarán esos bytes. Esto puede dar lugar a malas interpretaciones.

Por ejemplo:
TEXTO tiene CS=NONE
Conexión CS=NONE
insert into PRUEBA(TEXTO)values('Artículo') <-- Con acento en la I

Conexión CS=WIN1252
select TEXTO from PRUEBA(TEXTO)
Resulta en 'artÃ*culos'


TEXTO tiene CS=UNICODE_FSS
Conexión CS=UTF-8 desde la web
insert into PRUEBA(TEXTO)values('Artículo') <-- Con acento en la I

Conexión CS=WIN1252 desde Windows
select TEXTO from PRUEBA(TEXTO)
Resulta en 'artículos' porque el cliente Firebird transforma de UNICODE_FSS a WIN1252
Responder Con Cita
  #5  
Antiguo 13-09-2022
novato_erick novato_erick is offline
Miembro
 
Registrado: ago 2010
Ubicación: Panamá
Posts: 396
Poder: 14
novato_erick Va por buen camino
Cita:
duilioisola:
Desde la web se metía texto en formato UTF-8 y desde Windows se leia como WIN-1252. Lo mismo sucedía cuando se escribía en windows y se leia en la web.
Hola es correcto eso mismo es lo que me pasa igual intente cambiar a nivel de interfaz el tipo de codificación la info que provenia de la base de datos resultando muchas veces frustrada.

Este ejemplo para mi me resulta muy simple y comprensivo, no tengo una gran especialidad en Base de Datos lo que manejo me ah sido útil y funcional Aqui es donde uso la frace de todo programador: Si funciona no lo toques .

Cita:
Por ejemplo:
TEXTO tiene CS=NONE
Conexión CS=NONE
insert into PRUEBA(TEXTO)values('Artículo') <-- Con acento en la I

Conexión CS=WIN1252
select TEXTO from PRUEBA(TEXTO)
Resulta en 'artÃ*culos'


TEXTO tiene CS=UNICODE_FSS
Conexión CS=UTF-8 desde la web
insert into PRUEBA(TEXTO)values('Artículo') <-- Con acento en la I

Conexión CS=WIN1252 desde Windows
select TEXTO from PRUEBA(TEXTO)
Resulta en 'artículos' porque el cliente Firebird transforma de UNICODE_FSS a WIN1252
y realmente este tema suena interesante
Cita:
Para migrar la base de datos me hice una pequeña aplicación que leia la estructura de la base de datos y crea otra modificando los campos "texto" para agregarles el CHARSET (CHARACTER SET UNICODE_FSS).
Excelente aporte para migrar la DB. En teoría usando UNICODE pasará sin problema?, lo que me das a entender es simplemente pasar la estructura a UNICODE y luego su metadatos a la ultima versión de Firebird eso en teoría me quitará los dolores de cabeza de usar un Backup para luego Restaurar suena simple pero algo de trabajo no estaría mal.

suena interesante lo de tu "Pequeña aplicación" ya que yo utilizo SQL Manager Personal para exportar extructura pero el tuyo extrae y crea otra con la modificación de datos no quiero sonar perezoso pero tendría un costo si es asi escribeme en el privado o por aquí para que los participantes podamos conocer dicho aporte.

Agradezco tu pronta y esperada respuesta;

Saludos;

novato_erick
Responder Con Cita
  #6  
Antiguo 13-09-2022
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.040
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Creo que con que cambies los campos implicados por utf8 ya irá bien.
Y si estás usando dominios (que siempre es lo más adecuado) será más fácil porque sólo tendrás que cambiar su declaración.
Código SQL [-]
/* create domain domNombre varchar(64) character set ISO8859_1;  /* fb < 2.1 */ 
create domain domNombre varchar(64) character set UTF8 collate ES_ES_CI_AI default '';   /* fb >= 2.1 **/
Eso sí, lo mismo tendrás que "recodificar" los datos que tengas guardados ya, hacer un update leyendo lo que hay y convirtiéndolo al nuevo formato.
Responder Con Cita
  #7  
Antiguo 13-09-2022
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Dado el interés, os dejo aquí la aplicación para leer una Base de Datos Firebird y crear otra con los campos texto con Charset UNICODE_FSS.

Esta aplicación utiliza los componentes FreeIB y está desarrollada en Delphi 6.
Creo que está todo contenido dentro del ZIP.
Además, está la aplicación compilada, lista para utilizar.

Pedirá una base origen y su CharSet.
En mi caso el CharSet es NONE.

La base destino no debería existir, para que la aplicación la cree antes de traspasar los datos de una a otra.

Los Checks arriba a la derecha son todos los datos que se van a traspasar.
Iniciará traspasando los de la primera columna en orden (Generators, Exceptions, Domains, Tables)
Luego hará el "Data Pump" en donde tratará de leer los datos y escribirlos en la base de datos destino.
En este punto podrían darse problemas de "Transliterate". Esto es problemas donde no puede convertir lo que lee en Unicode válido.

Luego de esto, con las tablas pobladas, pasará a crear el resto de estructura de la base (PK, Unique Indices, FK, ...)

Cuando llega a pasar procedimientos, he hecho un algoritmo para tratar de pasarlos en orden de dependencia. Hace cinco pasadas y reordena los procedimientos lo mejor que puede... Espero que no os falle.

A tener en cuenta:
Ya que es un proyecto para mis bases de datos, hay alguna cosa que podría fallar y vuestras bases.

Código Delphi [-]
procedure TFMMain.TraspasarTables;
Si el dominio de un campo de una tabla es IMAGEN, lo crea con el dominio IMAGENES en destino.
Si el dominio de un campo de una tabla es IMAGEN_P, lo crea con el dominio IMAGENES en destino.
Si el dominio de un campo de una tabla es binario (BLOB SUB_TYPE 0), lo crea con el dominio IMAGENES en destino.
Si el dominio de un campo de una tabla es NOTAS_UNICODE, lo crea con el dominio NOTAS en destino.
Si el dominio de un campo de una tabla es PROTECCION, lo crea con el dominio NOTAS en destino.
Si el dominio de un campo de una tabla es APUNTES, lo crea con el dominio NOTAS en destino.
Si el dominio de un campo de una tabla es TEXTO, lo crea con el dominio NOTAS en destino.
Si el dominio de un campo de una tabla es blob tipo texto (BLOB SUB_TYPE 1), lo crea con el dominio NOTAS en destino.

Código Delphi [-]
procedure TFMMain.Pump;
Si el campo se llama ARTICULO reemplazo ñ, Ñ por N. (En mi base de datos, esto es el código de un artículo y no permito esos caracteres.)

Si por algún motivo alguien necesita algo un poco más especial o necesita que quite las transformaciones que he hecho, puede modificar el código y recompilarlo.
Si esto no fuera posible, enviarme un mensaje privado y trataré de adaptar el código.
Si tampoco fuera posible, y sigue fallando nos ponemos en contacto y si me pasáis vuestra base de datos. Con esto seguro que podré hacer las modificaciones necesarias.

Saludos,
Imágenes Adjuntas
Tipo de Archivo: png firebird_clone.png (15,2 KB, 5 visitas)
Archivos Adjuntos
Tipo de Archivo: zip FirebirdClone.zip (387,7 KB, 5 visitas)
Responder Con Cita
  #8  
Antiguo 13-09-2022
novato_erick novato_erick is offline
Miembro
 
Registrado: ago 2010
Ubicación: Panamá
Posts: 396
Poder: 14
novato_erick Va por buen camino
Cita:
duilioisola

Si el campo se llama ARTICULO reemplazo ñ, Ñ por N. (En mi base de datos, esto es el código de un artículo y no permito esos caracteres.)
Si tienes razón igual ya no lo permito anivel de interfaz aunque unos usuarios me preguntan porque no lo incluyo pero aunque trate de explicar no entenderán a nivel interno de una DB

Saludos
Responder Con Cita
  #9  
Antiguo 13-09-2022
novato_erick novato_erick is offline
Miembro
 
Registrado: ago 2010
Ubicación: Panamá
Posts: 396
Poder: 14
novato_erick Va por buen camino
Cita:
Empezado por Casimiro Notevi Ver Mensaje
Creo que con que cambies los campos implicados por utf8 ya irá bien.
Y si estás usando dominios (que siempre es lo más adecuado) será más fácil porque sólo tendrás que cambiar su declaración.
Código SQL [-]
/* create domain domNombre varchar(64) character set ISO8859_1;  /* fb < 2.1 */ 
create domain domNombre varchar(64) character set UTF8 collate ES_ES_CI_AI default '';   /* fb >= 2.1 **/
Eso sí, lo mismo tendrás que "recodificar" los datos que tengas guardados ya, hacer un update leyendo lo que hay y convirtiéndolo al nuevo formato.
Estoy en proceso de buscar la mejor manera de Adaptar mi DB a nuevos requerimientos y lo había contemplado pero esto de migrar no es algo sencillo.

Honestamente eso de Dominio lo lo habia contemplado si no es que lo mencionas pasaría por desapersivido dicha información Casimiro gracias la leí lo útil que es.

en Fin de Ascii a otro dipo de Charset todo incurre por los cambios que maneja Firebird si no hubiera incurrido a la necesidad de actualizar a 4.0 creo que todo estaría de maravillas tal cual ha pasado hasta entonces.

les comentaré más adelante cómo les fue. Les agradezco enormemente sus aportes a
duilioisola y Casimiro

Saludos;
Responder Con Cita
  #10  
Antiguo 13-09-2022
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.040
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por novato_erick Ver Mensaje
... en Fin de Ascii a otro dipo de Charset todo incurre por los cambios que maneja Firebird si no hubiera incurrido a la necesidad de actualizar a 4.0 creo que todo estaría de maravillas tal cual ha pasado hasta entonces....
Creo recordar que está desde la v2.1
Responder Con Cita
  #11  
Antiguo 13-09-2022
novato_erick novato_erick is offline
Miembro
 
Registrado: ago 2010
Ubicación: Panamá
Posts: 396
Poder: 14
novato_erick Va por buen camino
Cita:
Empezado por Casimiro Notevi Ver Mensaje
Creo recordar que está desde la v2.1
Correcto amigo;


Pero hay dolores de migrar desde la versión 2.5x a la 3 o 4 de Firebird con los Charset
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
CharSet Firebird Neeruu Varios 5 03-09-2016 19:17:23
Carácter en Firebird utilizando Charset ASCII novato_erick Firebird e Interbase 7 06-08-2015 19:49:33
Firebird 2.5 UTF8 ander Firebird e Interbase 11 05-06-2013 13:15:07
Firebird 2.5 Utf8 Problema Con La ñ agidar Firebird e Interbase 3 16-08-2011 18:02:16
Firebird 2.5 y UTF8 Chandra_ Firebird e Interbase 14 05-11-2010 20:27:44


La franja horaria es GMT +2. Ahora son las 15:55:24.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi