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 05-11-2010
Gallosuarez Gallosuarez is offline
Miembro
 
Registrado: feb 2007
Posts: 92
Poder: 18
Gallosuarez Va por buen camino
Smile Algunas razones...

Cita:
Empezado por guillotmarc Ver Mensaje
Donde se he equivocado un poco Gallosuarez es en los beneficios de no usar Unicode. Por ejemplo, respecto al tamaño Firebird utiliza UTF8, que o bien estoy muy equivocado o bien para la inmensa mayoría de los símbolos de nuestro alfabeto solo necesita 1 byte (aunque los símbolos especiales como la ñ, van a usar más bytes, ya que UTF8 tiene un tamaño de letra variable). Y respecto a los "Collates", Firebird 2.5 ya ha incorporado un UNICODE_CI_AI, por lo que ya no hay muchas razones para no usar Unicode.
De acuerdo a las pruebas que he realizado, me he encontrado que al tratar de utilizar un UUID (Universal Unique Identifier [Identificador Único Universal]) utilizando el juego de caracteres UTF8, al tratar de insertar dicho campo Firebird protesta. La primera suposición que hice fue que al utilizar UTF8 el tamaño del campo ID tendría que ser mayor (Firebird especifica que un UUID debe de ser un VARCHAR(16), y puesto que UTF8 puede utilizar 1,2,3 y hasta 4 bytes para representar un caracter; entonces tendría que utilizar un campo mayor. Por lo tanto, el campo debe de ser mayor, el índice que se crea es mayor y al final de cuentas tu tabla crece mas, y esto repercute en tamaño y en desempeño (de allí mi afirmación en el primer "post").

Otra cosa que note es que al insertar campos que contienen á, é, í, ó, ú, ñ, Ñ (y algunos otros como la u con diéresis), efectivamente utilizaban dos caracteres. Esto me acarreo el siguiente problema: la función CHAR_LENGTH me reporta un conteo mayor en la longitud de la cadena. Tengo funciones que hacen el cálculo automático del RFC (CIF para otro países) y dejaron de funcionar correctamente.

Como pueden ver, estos son los problemas que me he encontrado al tratar de utilizar UTF8. Al menos para mi si son algunas razones para no utilizarlo (por el momento), sin embargo, me pregunto si hay alguien en el foro que ya haya sorteado todos estos problemas. Tal vez nos pueda comentar y nos convenza de que es mejor opción UTF8.

Saludos,
Gerardo Suárez Trejo

Un saludo a Guillotemarc, sus comentarios siempre me parecen atinados y enriquecedores en la mayoría de los casos.
Responder Con Cita
  #2  
Antiguo 05-11-2010
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.055
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por Gallosuarez Ver Mensaje
[..]
Otra cosa que note es que al insertar campos que contienen á, é, í, ó, ú, ñ, Ñ (y algunos otros como la u con diéresis), efectivamente utilizaban dos caracteres. Esto me acarreo el siguiente problema: la función CHAR_LENGTH me reporta un conteo mayor en la longitud de la cadena. Tengo funciones que hacen el cálculo automático del RFC (CIF para otro países) y dejaron de funcionar correctamente.
[..]
Ese caso en particular es fácil de solucionar, para los CIF sólo valen letras "normales" sin tildes: A,B,C,D,E, etc.
Responder Con Cita
  #3  
Antiguo 05-11-2010
Gallosuarez Gallosuarez is offline
Miembro
 
Registrado: feb 2007
Posts: 92
Poder: 18
Gallosuarez Va por buen camino
Smile Confundido...

Casimiro:

O no te sabes explicar , o yo no te entiendo..... porque no te sabes explicar.... (je, je, je) una pequeña broma.

Código SQL [-]
create or alter procedure PROPER_VOWEL (
    C char(1))
returns (
    VOWEL char(1))
AS
begin
  vowel = C;
  if (C in ('Á', 'a', 'á')) then vowel = 'A';
  if (C in ('É', 'e', 'é')) then vowel = 'E';
  if (C in ('Í', 'i', 'í')) then vowel = 'I';
  if (C in ('Ó', 'o', 'ó')) then vowel = 'O';
  if (C in ('Ú', 'u', 'ú')) then vowel = 'U';
end

Procedimiento almacenado que convierte un vocal acentuado a una vocal sin acento.... (se puede extender fácilmente para vocales con acento circunflejo en caso de idiomas como el Francés y el Portugués (creo).

Código SQL [-]
create or alter procedure CALC_RFC (
    A_PATERNO varchar(25),
    A_MATERNO varchar(25),
    NOMBRE varchar(30),
    F_NACIMIENTO date)
returns (
    RFC varchar(13))
AS
declare variable dd char(2); /* día de nacimiento */
declare variable mm char(2); /* mes de nacimiento */
declare variable aa char(2); /* año de nacimiento */
declare variable pv char(1) = ''; /* primera vocal en la cadena*/
declare variable cadena varchar(24);
declare variable i smallint = 1;
declare variable len smallint; /* longitud de cadena*/
begin
  dd = lpad(cast(extract(day from :f_nacimiento) as varchar(2)), 2, '0');
  mm = lpad(cast(extract(month from :f_nacimiento) as varchar(2)), 2, '0');
  aa = right(cast(extract(year from :f_nacimiento) as varchar(4)), 2);
  cadena = substring(a_paterno from 2);
  len = char_length(cadena);
  i = 1;
  while (i < len) do
  begin
    execute procedure proper_vowel(substring(cadena from 1 for 1))
    returning_values pv;
    if (pv in ('A', 'E', 'I', 'O', 'U')) then leave;
    cadena = substring(cadena from 2);
    i = i + 1;
  end
  rfc = left(:a_paterno, 1) || pv || coalesce(left(:a_materno, 1), 'X') ||
    left(:nombre, 1) || aa || mm || dd;
end

Procedimiento almacenado que calcula (en automático) el RFC de una persona utilizando su Nombre, Apellido Paterno, Apellido Materno y su fecha de nacimiento. Como te puedes dar cuenta, este último procedimiento almacenado uso la función CHAR_LENGTH. Si utilizo UTF8 la longitud de la cadena es errónea, además de no encontrar las vocales acentuadas puesto que ahora se representa en dos bytes, ¿me explico?

Saludos,
Gerardo Suárez Trejo

Última edición por Gallosuarez fecha: 05-11-2010 a las 17:25:40.
Responder Con Cita
  #4  
Antiguo 05-11-2010
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Cita:
Empezado por Gallosuarez Ver Mensaje
Casimiro:

O no te sabes explicar , o yo no te entiendo..... porque no te sabes explicar.... (je, je, je) una pequeña broma.

Código SQL [-]create or alter procedure PROPER_VOWEL ( C char(1)) returns ( VOWEL char(1)) AS begin vowel = C; if (C in ('Á', 'a', 'á')) then vowel = 'A'; if (C in ('É', 'e', 'é')) then vowel = 'E'; if (C in ('Í', 'i', 'í')) then vowel = 'I'; if (C in ('Ó', 'o', 'ó')) then vowel = 'O'; if (C in ('Ú', 'u', 'ú')) then vowel = 'U'; end


Procedimiento almacenado que convierte un vocal acentuado a una vocal sin acento.... (se puede extender fácilmente para vocales con acento circunflejo en caso de idiomas como el Francés y el Portugués (creo).

Código SQL [-]create or alter procedure CALC_RFC ( A_PATERNO varchar(25), A_MATERNO varchar(25), NOMBRE varchar(30), F_NACIMIENTO date) returns ( RFC varchar(13)) AS declare variable dd char(2); /* día de nacimiento */ declare variable mm char(2); /* mes de nacimiento */ declare variable aa char(2); /* año de nacimiento */ declare variable pv char(1) = ''; /* primera vocal en la cadena*/ declare variable cadena varchar(24); declare variable i smallint = 1; declare variable len smallint; /* longitud de cadena*/ begin dd = lpad(cast(extract(day from :f_nacimiento) as varchar(2)), 2, '0'); mm = lpad(cast(extract(month from :f_nacimiento) as varchar(2)), 2, '0'); aa = right(cast(extract(year from :f_nacimiento) as varchar(4)), 2); cadena = substring(a_paterno from 2); len = char_length(cadena); i = 1; while (i < len) do begin execute procedure proper_vowel(substring(cadena from 1 for 1)) returning_values pv; if (pv in ('A', 'E', 'I', 'O', 'U')) then leave; cadena = substring(cadena from 2); i = i + 1; end rfc = left(:a_paterno, 1) || pv || coalesce(left(:a_materno, 1), 'X') || left(:nombre, 1) || aa || mm || dd; end


Procedimiento almacenado que calcula (en automático) el RFC de una persona utilizando su Nombre, Apellido Paterno, Apellido Materno y su fecha de nacimiento. Como te puedes dar cuenta, este último procedimiento almacenado uso la función CHAR_LENGTH. Si utilizo UTF8 la longitud de la cadena es errónea, además de no encontrar las vocales acentuadas puesto que ahora se representa en dos bytes, ¿me explico?

Saludos,
Gerardo Suárez Trejo
Esta claro que no deberías tener estos problemas.

Me pregunto si las variables varchar y char de tu procedimiento almacenado están realmente en UTF8. Los campos ya me imagino que sí, pero estas variables en ningún momento se les dice su charset, por lo tanto quizás estén en el charset predeterminado de la base de datos.

Comprueba cual es el charset predeterminado de tu base de datos :

Código SQL [-]
select rdb$character_set_name from rdb$database

Es probable que tus procedimientos almacenados solo funcionen correctamente si el charset de la base de datos es UTF8.

NOTA: Asegúrate mirando cuando vale la variable len de tu SP, y cuanto es esa misma longitud si lo consultas directamente sobre el campo.

Código SQL [-]
select char_length(a_paterno) from tabla where id = x

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #5  
Antiguo 05-11-2010
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.055
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Será que no me explico bien
Responder Con Cita
  #6  
Antiguo 05-11-2010
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Hola Gerardo.

Cita:
Empezado por Gallosuarez Ver Mensaje
De acuerdo a las pruebas que he realizado, me he encontrado que al tratar de utilizar un UUID (Universal Unique Identifier [Identificador Único Universal]) utilizando el juego de caracteres UTF8, al tratar de insertar dicho campo Firebird protesta. La primera suposición que hice fue que al utilizar UTF8 el tamaño del campo ID tendría que ser mayor (Firebird especifica que un UUID debe de ser un VARCHAR(16), y puesto que UTF8 puede utilizar 1,2,3 y hasta 4 bytes para representar un caracter; entonces tendría que utilizar un campo mayor. Por lo tanto, el campo debe de ser mayor, el índice que se crea es mayor y al final de cuentas tu tabla crece mas, y esto repercute en tamaño y en desempeño (de allí mi afirmación en el primer "post").
Yo tengo entendido que los campos UUID los tienes que definir como varchar(16) pero con el charset OCTETS.

Ejplo. CREATE DOMAIN UUID AS VARCHAR(16) CHARACTER SET OCTETS;

NOTA: De la misma forma que te daba problemas con Unicode, si intentas guardar un UUID en un varchar(16) con iso8859_1 lo más probable es que te de un transliteration error (o sea que los carácteres que intentas guardar no son válidos en el alfabeto soportado por iso8859_1).

El charset OCTETS acepta los caracteres que se le envían en el mismo binario en que los recibe, no hace ni intenta hacer ninguna manipulación con ellos.

Cita:
Empezado por Gallosuarez Ver Mensaje
Otra cosa que note es que al insertar campos que contienen á, é, í, ó, ú, ñ, Ñ (y algunos otros como la u con diéresis), efectivamente utilizaban dos caracteres. Esto me acarreo el siguiente problema: la función CHAR_LENGTH me reporta un conteo mayor en la longitud de la cadena. Tengo funciones que hacen el cálculo automático del RFC (CIF para otro países) y dejaron de funcionar correctamente.

Como pueden ver, estos son los problemas que me he encontrado al tratar de utilizar UTF8. Al menos para mi si son algunas razones para no utilizarlo (por el momento), sin embargo, me pregunto si hay alguien en el foro que ya haya sorteado todos estos problemas. Tal vez nos pueda comentar y nos convenza de que es mejor opción UTF8.
¿ Estás seguro ?. No debería.

CHAR_LENGTH (o CHARACTER_LENGTH) debería devolver el número de caracteres de la cadena (independientemente de su tamaño).

OCTET_LENGTH sí que devuelve el tamaño en bytes ocupado por la cadena.

Cita:
Empezado por Gallosuarez Ver Mensaje
Un saludo a Guillotemarc, sus comentarios siempre me parecen atinados y enriquecedores en la mayoría de los casos.
Gracias por la confianza .
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
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
¿''?reportmanager y delphi 2010 VCL con firebird 2.1 UTF8 JXJ Varios 0 19-08-2010 19:22:03
UTF8 La maldicion Softweb Varios 3 25-03-2010 13:45:39
Cambiar CHARACTER SET NONE a UTF8 en FIREBIRD 1.5 ASAPLTDA Firebird e Interbase 1 06-03-2008 00:22:54
Codificar texto en UTF8 xio Internet 0 29-10-2007 18:10:19


La franja horaria es GMT +2. Ahora son las 22:06:55.


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