PDA

Ver la Versión Completa : ¿El uso de firebird como una base seria no es tan correcto?


IVAND
04-12-2007, 15:57:19
Hola a todos utilizo firebird 1.5 , tengo una tabla con la siguiente estructura

CREATE TABLE DET_DIARIO (
KEY_DET_DIARIO INTEGER NOT NULL,
KEY_CAB_DIARIO INTEGER,
KEY_PLAN_CTAS INTEGER,
DESCRIPCION CHAR(60),
DEBE NUMERIC(15,2),
HABER NUMERIC(15,2),
KEY_MOV_BANCO INTEGER,
COD_SUCURSAL INTEGER
);


pero mi pregunta fue hace un tiempo en este mismo foro que porque si tengo un dato como por ejemplo 120,30 , esta base de datos me lo graba tal como lo digito pero si escribo 1201,30 la base me muesta 121,3099999999999997 cuando salgo del campo me muestara 1201,30 pero al momento de hacer los calculos estos son totalmente equivocados pues la suma me da un valor de -0,001 lo cual impide que este diario contable se cierre de manera correcta

En este mismo foro se comento tal problema pero si alguien de uds lo ha podido corregir me ayudaria enormemente

Si el problema persiste creo que dejare de usar esta base de datos o el problema tambien la tienen otras base de datos

Ojo este ejemplo lo estoy realizando desde el Ibexpert


Imaginesen este caos en un banco :rolleyes:

Gracias por su interes

jhonny
04-12-2007, 16:16:42
Bueno, recuerdo muy bien tu hilo anterior ya que yo estaba unido a tu causa y estaa totalmente de acuerdo contigo, la verdad es que es algo demaciado molesto y complicado de llevar, recuerdo que en ese hilo llegamos a la conclusión de que quizá cambiando la BD a Dialecto 3 mejoraria el asunto, a partir de ese entonces comenzamos un proyecto en mi empresa para cambiar de Dialecto nuestra base de datos y realizar las pruebas necesarias con bases de datos con datos veridicos, aún estamos realizando estas pruebas pero debo decirte que hasta ahora todas han sido satisfactorias, ya no tenemos problemas al sumar todos esos valores debido a que al parecer con Dialecto3 la cosa es diferente, poniendo tu caso como ejemplo:

Antes en Dialecto1, veiamos lo mismo que tu al digitar un valor, si digitabamos:

1201,35 él almacenaba 1201,359999999999999

Ahora con Dialecto3, tambien se "inventa" esos números de mas pero de manera diferente, si digitamos:

1201,30 él guarda 1201,34999999999

Por lo que al redondear a dos decimales en nuestros reportes tendremos el valor correcto :).

Para probar eso hicimos un Sum de toda nuestra tabla de contabilidad, luego de haber "redigitado" (entre comillas porque hice un software que hacia eso automaticamente, simulando que alguien los digitaba) de nuevo todos los documentos y el saldo nos dio 0, cuando antes nos mostraba 0.01.

Nota: Para cambiar de Dialecto1 a Dialecto3 tuve extraer el Metadata y con el mismo IbExpert ejecutarlo en una BD creada con el nuevo Dialecto, el Script mostró muchos errores debido a la incompatibilidad entre los dos dialectos y a medida que los iba corrigiendo, lo ejecutaba de nuevo hasta corregir todos y cada uno de ellos, tanto en los Stored Procedures, como en la aplicación.

Lepe
04-12-2007, 17:51:23
When you create a domain or column with a NUMERIC or DECIMAL datatype, InterBase
determines which datatype to use for internal storage based on the precision and scale
that you specify and the dialect of the database.

NUMERIC and DECIMAL datatypes that are declared without either precision or scale are
stored as INTEGER.

Defined with precision, with or without scale, they are stored as SMALLINT, INTEGER,
DOUBLE PRECISION or 64-bit integer. Storage type depends on both the precision and the
dialect of the database. Table 4.2 describes these relationships.

Precision Dialect 1 Dialect 3
1 to 4 SMALLINT for NUMERIC datatypes SMALLINT
INTEGER for DECIMAL datatypes

5 to 9 INTEGER INTEGER
10 to 18 DOUBLE PRECISION INT64


NUMERIC and DECIMAL datatypes with precision greater than 10 always produce an error
when you create a dialect 2 database. This forces you to examine each instance during a
migration. For more about migrating exact numerics, see “Migrating databases with
NUMERIC and DECIMAL datatypes” on page 67.

Al guardarse en dialecto 1 con 15 de precisión, estás usando el double precision, no apto para valores monetarios.

jhonny: no he hecho pruebas, pero quizás el problema continúe por no realizar una correcta migración de datos. Ya digo, en tu caso particular no tengo ni idea.


Lamentablemente, la ignorancia es así, criticamos por desconocimiento y arrogantemente.

PD: Ese libro es gratuito y descargable desde www.ibphoenix.com

Saludos

Lepe
04-12-2007, 17:56:39
Y vamos a la página 67 para una correcta migración de los datos:

1. Back up your original database. Read the “migration” chapter in Getting
Started to determine what preparations you need to make before migrating
the database. Typically, this includes detecting metadata that uses double
quotes around strings. After making necessary preparations, back up the
database using its current GBAK version and restore it using InterBase 6.
2. Use gfix -set_db_SQL_dialect 3 to change the database to dialect 3
3. Use the ALTER COLUMN clause of the ALTER DATABASE statement to change the
name of each affected column to something different from its original name.
If column position is going to be an issue with any of your clients, use ALTER
COLUMN to change the positions as well.
4. Create a new column for each one that you are migrating. Use the original
column names and if necessary, positions. Declare each one as a DECIMAL or
NUMERIC with precision greater than 9.
5. Use UPDATE to copy the data from each old column to its corresponding new
column:
UPDATE tablename
SET new_col_name = old_col_name;
6. Check that your data has been successfully copied to the new columns and
drop the old columns.
Note If you are migrating exact numeric columns to a dialect 1 database in InterBase 6,
no special steps are needed. A dialect 1 database in InterBase 6 behaves just like an
InterBase 5 database. Dialect 1 is an old standard, however, and will eventually not be
supported by InterBase.

Saludos

Lepe
04-12-2007, 18:08:57
jhonny: una pregunta, ¿Qué componentes usas para conectar a Firebird? Yo uso los MDO y me crea los campos persistentes como TBCDFields (Binay Coded Decimal) que es el representante sin pérdida de decimales.

Si en Delphi usas aún TFloatFields, vendría por ahí el fallo de guardar mal los decimales (supongo).

Ya digo, Firebird 1.5 en dialecto 3 con numeric(10,2) + MDOLIB = números correctos en los DBEdits, en Base de Datos "espulgada" con IB Expert y en los cálculos entre varios campos de tipo BCD.

Saludos.

IVAND
04-12-2007, 18:20:11
Gracias amigo Jonny entonces tu tesis es que migrando a dialecto 3 estos problemas desaparecen o al menos se minimizan , no has encontrado otra manera de hacerlo pues me va a ocurrir lo mismo que a ti , pero bueno ahi le vamos a dar ,

Nota :Lamentablemente, la ignorancia es así, criticamos por desconocimiento y arrogantemente. Sr. Lepe , todos somos ignorantes , si no pregunto seguiria en mi ignorancia, no lo hago de manera arrogante ni mucho menos simplemente es por mi ignorancia y desconocimiento pero igual gracias por su ayuda

Lepe
04-12-2007, 18:36:35
Sr. Lepe , todos somos ignorantes , si no pregunto seguiria en mi ignorancia, no lo hago de manera arrogante ni mucho menos simplemente es por mi ignorancia y desconocimiento pero igual gracias por su ayuda

Estoy de acuerdo en todo lo que has dicho. Cuando dije "arrogantemente" me refería en general, al ser humano de hoy día, de verdad que no pensaba en tí concretamente, bueno quizás pensaba en jhonny :p :p :D ]:-D.

OFFTOPIC: no sé por qué, pero hoy tengo ganas de "guerra sana" ;).

Saludos

juanelo
04-12-2007, 18:39:12
Nota :Lamentablemente, la ignorancia es así, criticamos por desconocimiento y arrogantemente. Sr. Lepe , todos somos ignorantes , si no pregunto seguiria en mi ignorancia, no lo hago de manera arrogante ni mucho menos simplemente es por mi ignorancia y desconocimiento pero igual gracias por su ayuda

Que tal,
En lo que no estoy de acuerdo es en el titulo de tu hilo :

"El uso de firebird como una base seria no es tan correcto"

Ya que aqui efectivamente estas pecando de arrogancia, ya que te crees con la suficiente "autoridad" o "conocimiento" para poder hacer esa aseveración, cuando mas de 2.500.000 de personas han descargado firebird y ademas de ser nombrado el proyecto del mes por sourceforge no creo que sea por ser una base de datos "broma" (o no tan seria como afirmas).

El hecho que te esté dando problemas lo atribuyo a tu falta de conocimiento y no a la base de datos en si.

Saludos

RolphyReyes
04-12-2007, 19:10:13
Estoy de acuerdo con juanelo, el hecho de que tengas problemas no necesariamente tiene que ser la BD sino la falta de informacion de como manejarla.

Si fuese asi FireBird no estaria donde esta y ademas las grandes compañias que la han utilizado (o siguen utilizandola) no se harian de mencion.

Antes de formular algun tipo de comentario sobre algo trata de tener mas informacion sobre el mismo.

jhonny
04-12-2007, 19:19:53
Estoy de acuerdo en todo lo que has dicho. Cuando dije "arrogantemente" me refería en general, al ser humano de hoy día, de verdad que no pensaba en tí concretamente, bueno quizás pensaba en jhonny :p :p :D ]:-D.


Ahhh si?, Pues vamos pal Ring :D.

En cuanto a los conectores a base de datos de ese proyecto debo contarte que son los BDE, es un proyecto plagado de BDE por lo que nos a dado real y sincera pereza cambiar toda esa cosa mal diseñada por otra (Me refiero al aplicativo, ya que tiene conectores en casi todos los formularios :D). De hecho hemos pensado en arrancar un nuevo proyecto mejor diseñado, con un modelo veridico y con conectores distintos (Y que sean faciles de cambiar), pero antes teniamos que arreglar este problema de los centavos, el problema ahora es que el BDE no acepta tipos Numeric cuando la BD esta en Dialecto3, por lo que ensayamos con el Double Precision y el efecto es el que mencione anteriormente minimizando en gran manera el problema, aunque la verdad es que no sabia lo de los BCD ya que es otro Tip a tener en cuenta para el nuevo proyecto, Gracias Lepe :).

En cuanto a exportar los datos, pues me parece que esa es una tecnica valida y que tambien tiene derecho a ser probada :).

Por otro lado, debo confesarles que hubo un tiempo donde estuve tan desanimado como IVAND de Firebird, pero luego de leer este tipo de cosas, hacer las mil y una pruebas con Dialecto3 (Y eso que todavia faltan mas pruebas), me he vuelto a animar... ademas por la futura versión 2.1 que tiene muchas cosas super-interesantes :).

eduarcol
04-12-2007, 19:26:08
Ahhh si?, Pues vamos pal Ring :D.


Me avisas para ir encendiendo las luces...

IVAND
04-12-2007, 20:26:20
Gracias Lepe por tu aclaracion , yo tambien aclaro lo siguiente no es que uno se cree con la autoridad ni nada de eso, lo del titulo es solo una pregunta de una persona que se encuentra con un problema para mi muy dificil de tratar , aqui nadie es una total autoridad se supone que es un foro para preguntar algo y eso

Si mi titulo les parecio algo duro pues mil disculpas pero repito es solo una pregunta no una aseveracion
Gracias por entender

Bueno cambiare a dialecto 3 y veremos como nos va pues creo que ese sera el mejor camino

Lepe
04-12-2007, 21:21:47
Hombre, "gracias al título" no ha pasado desapercibido el hilo :D.

Saludos

Al González
05-12-2007, 07:37:13
¡Hola a todos!

...pero repito es solo una pregunta no una aseveracion...

Bueno, entonces que algún moderador corrija el título y le ponga los signos de interrogación que toda pregunta lleva.

Aunque, siendo justos, creo que quedaría mejor el título Raro almacenamiento de decimales en Firebird.

Un abrazo serio y políticamente correcto.

Al González. :)

Casimiro Notevi
05-12-2007, 09:12:09
Después de más de 10 años usando interbase->firebird... me parece muy seria :D


P.d. para usar valores con decimales siempre uso double.

Lepe
05-12-2007, 13:47:10
P.d. para usar valores con decimales siempre uso double.

Interesante casimiro, ¿realizas algún tipo de redondeo? ¿en delphi asignas al campo Currency:= true?

Me deja intrigado tu afirmación.

Saludos

hecospina
05-12-2007, 14:33:34
Hola
Segun he leido aun hace la coneccion por BDE
tubimos el mismo problema en la empresa pero trabajabamos con Paradox
Hicimos una configuacion en el alias que se manejaba para la base de datos colocando ENABLE BCD en true y nos redujo mucho el problema
No se si maneja alias y si ya lo esta configurado asi
Puede hacer la prueba y nos cuenta como le fue

jhonny
05-12-2007, 14:55:32
Bueno, creo que la combinación de todas estas cosas ayudara a resolver el problema :).

Casimiro Notevi
05-12-2007, 15:16:48
Interesante casimiro, ¿realizas algún tipo de redondeo? ¿en delphi asignas al campo Currency:= true?
Me deja intrigado tu afirmación.
Saludos

Ni siquiera sé dónde está eso de currency:=true :confused:

Yo creo los campos (y tablas y todo) en un script.sql y desde delphi uso los querys y nada más, en ningún sitio indico si es currency u otra cosa, son simplemente valores.
Cuando son importes totales de un documento (pedido,factura,etc.) sí guardo los valores redondeados a 2 decimales (euros), pero sólo en los importes totales (base,iva,total) no en los precios de los artículos (por ejemplo), estos es según lo que configure cada cliente, los decimales que quieran cada uno (la presentación) ya que internamente van todos los decimales.

jhonny
05-12-2007, 15:41:45
Lo de currency es una propiedad de los campos, la puedes ver haciendo click en el editor de campos sobre un campo numerico.

Lepe
05-12-2007, 18:00:26
Después de repasar todo lo aportado por los compañeros y mirar detenidamente el datadef.pdf, estamos en la misma situación. En resumen:

Dialecto 1 con precision mayor a 9 usando DOUBLE PRECISION, siempre tendrá problemas de decimales que pueden ser redondeado donde legalmente se pueda (como bien dijo Casimiro, en los totales; nunca se puede redondear en cálculos intermedios)

Dialecto 3 con precisión mayor a 9 , da igual si se usa NUMERIC(10,2), DECIMAL(10,2) o DOUBLE PRECISION, Firebird usará un INT64 internamente para representar el número y no habrá pérdida de decimales.

Si la precisión es menor o igual a 9, internamente se usará smallint, integer, double precision, etc. dependiendo del tipo usado. En este caso no queda más remedio que ver el pdf para entender como se guarda internamente.

Saludos

Casimiro Notevi
05-12-2007, 19:11:12
Lo de currency es una propiedad de los campos, la puedes ver haciendo click en el editor de campos sobre un campo numerico.

ummm, pues no, nunca me ha hecho falta usar esa propiedad.

Delfino
05-12-2007, 19:49:19
OFFTOPIC: no sé por qué, pero hoy tengo ganas de "guerra sana"
y de guerra santa? no tienes ganas? :D

Que efecto tiene asignar la propiedad currency a True en un field???

Lepe
05-12-2007, 20:15:58
y de guerra santa? no tienes ganas? :D

... no lo sabes tú bien, con sangre y todo de por medio... pero me contengo :p.


Que efecto tiene asignar la propiedad currency a True en un field???

Teniendo un campo Float (TFloatField), da la apariencia de ser un Currency: muestra el símbolo de la moneda y dos decimales, al editar también se mantiene este formato (si EditFormat y DisplayFormat están en blanco).

Por eso lo pregunté, ya que si es un double precision y estableces la propiedad en True, el propio TField puede camuflar el valor real que tiene asignado. Por ejemplo:

valor real 2,539
valor mostrado en el DBedit (por currency:= true) 2,54


Saludos

IVAND
05-12-2007, 22:52:41
Esto se puso interesante , pues aqui va otra pregunta si uso double precision el problema desaparecera o no ? bueno eso lo voy a probar luego en el trabajo , pero a ud que ya tienen mucha experiencia en esto de los dialectos , cuales son los problemas mas comunes de migrar de dialecto 1 a dialecto 3 , hay que cambiar los querys o algo mas ?

Por lo que parece lo mejor sera usar dialecto 3 verdad?

Gracias por su aporte

jhonny
05-12-2007, 23:09:09
Esto se puso interesante , pues aqui va otra pregunta si uso double precision el problema desaparecera o no ? bueno eso lo voy a probar luego en el trabajo , pero a ud que ya tienen mucha experiencia en esto de los dialectos , cuales son los problemas mas comunes de migrar de dialecto 1 a dialecto 3 , hay que cambiar los querys o algo mas ?

Por lo que parece lo mejor sera usar dialecto 3 verdad?

Gracias por su aporte

Yo me encontre con los siguientes problemas comunes:

1) En dialecto 3 no debes usar comillas dobles (") para especificar un String, si no que debes usar comillas simples(').

2) Si en una consulta declaras un Alias, lo mejor será que lo uses, osea... si haces esto:


select c.nombre, sucursal.telefono from cliente c, sucursal s where s.id=c.id


Seguramente te dira que el campo telefono no existe ya que el alias es s no sucursal.

3) No debe repetir los campos en las insercciones, osea:
Si en alguna parte haces algo como...


insert into cliente(nombre, apellido, nombre) values('pepito', 'perez', 'pepito');


Te dira que estas redeclarando un campo en dicha consulta.

4) Si en Dialecto 1, tenias campos tipo Date donde guardabas la fecha y la hora, En Dialecto3 tendras que redeclararlos como TimeStamp, ya que el Date en Dialecto3 solo guarda la fecha y el Time la Hora, mientras que el TimeStamp guarda los dos valores como lo hacia el Dialecto1.


Bueno, esas son las cosas de las que me acuerdo hasta ahora, si me acuerdo de alguna otra mas adelante la anexare a la lista :).

RONPABLO
07-12-2007, 02:41:20
una inquietud... entonces me imagino que es recomendable asignar los valores de la siguiente forma??:


QConsulta.FieldByName('campo_doble').AsBCD := varFlotante;



y no así:



QConsulta.FieldByName('campo_doble').AsFloat := varFlotante;

Lepe
07-12-2007, 03:29:34
No serviría de nada. No se perdería definición en Delphi, pero al guardar en la base de datos, es cuando se produce el fallo (porque es inherente al tipo de datos double precision o Float en dialecto 1).

Bien es verdad, que teniendo un campo definido como Float y usando siempre .AsCurrency (tanto para mostrar como para asignar un valor al campo) estamos minimizando el problema. Queremos guardar el valor 23.30:

campo.AsCurrency := 23.30;
// en la base de datos quedará como 23.29999999 (un suponer)
tabla.post
ShowMesage(FloatToStr(campo.AsCurrency));
// al leer como Currency, normalmente se hace un redondeo y mostrará 23.30


El problema añadido, es que al utilizar ese valor en operaciones matemáticas los errores de decimales se van acumulando.

Saludos

Lepe
07-12-2007, 14:25:39
Al parecer este hilo puede llevar a confusiones al que busca en los foros.

En resumen: El problema es del tipo double precision y Float en todas las bases de datos.

Aunque como ya se ha visto en Firebird y Dialecto 3 se ha resuelto el problema.

Saludos

rastafarey
18-12-2007, 21:20:37
No queria opinar este hilo pero tengo que hacerlo.

Mira cual como se deberia llamr este hilo.

Yo no se usar firebird. Y por eso digo que no es seria.

Ven que asi se ve mejor.

Se supone que oaracle es un manejador de base de datos y me toco auditar un sistema con una base de datos que no orecle la podia soportar de lo mal diseñada que estaba. Eso tiraba errores por todoss las lados las mismas consultas devolbian valores diferentes y mucas cosas mas(Usaron una sola tabla para realizar un registro de personas con sus familiares nacionalidades y otro nmonto de datos mas).

Tabien sabian que c es el lenguaje mas potente que existe. pero he visto unas poruqerias de aplciaciones echas con c.

El titulo que sugeri antes tanpoco esta bien es un poco despota.
Pero este si.
Cuando el panadero es malo le echa la culpa a la harina.

Ese si esta bello.

egostar
18-12-2007, 21:31:49
Tabien sabian que c es el lenguaje mas potente que existe. pero he visto unas poruqerias de aplciaciones echas con c.


:D:D:D, según quien.........

Salud OS

rastafarey
18-12-2007, 21:42:45
Segun nadie.