Cuando en una tabla se declara una columna para que sea de tipo NUMERIC o de tipo DECIMAL es muy frecuente que se la declare mal. El error les ocurre más frecuentemente a los desarrolladores que están acostumbrados a usar los lenguajes xBase (dBase, Clipper, FoxPro, etc.)
¿Por qué?
Porque en los xBase si se declara a una columna como:
NUMERIC (5, 3)
eso significa que en esa columnas se guardarán 5 caracteres:
1 dígito en la parte entera
1 punto decimal
3 dígitos en la parte decimal
O sea que el primer número (el 5 en nuestro ejemplo) indica la cantidad total de caracteres incluyendo el punto decimal; y el segundo número (el 3 en nuestro ejemplo) indica la cantidad de decimales. Pero en SQL en general y en Firebird en particular: no se hace así.
Para conocer la forma en que se almacenan las columnas de tipo NUMERIC o DECIMAL en Firebird puedes leer estos dos artículos:
Veamos algunos ejemplos, si declaramos a una columna como:
NUMERIC(5, 3)
En xBase el máximo valor posible es 9.999; en SQL es 99999.999
NUMERIC(6, 2)
En xBase el máximo valor posible es 999.99; en SQL es 999999.99
NUMERIC(7, 5)
En xBase el máximo valor posible es 9.99999; en SQL es 9999.99999
NUMERIC(10, 6)
En xBase el máximo valor posible es 999.999999; en SQL es 999999999.999999
La forma en que se declaran las columnas de tipo NUMERIC en los xBase es sin duda más fácil de comprender y de recordar, pero en Firebird se hace de otra manera y por supuesto es a la manera de Firebird la que debemos usar cuando declaramos una columna en Firebird.
Si recuerdas como se almacenan internamente las columnas NUMERIC y DECIMAL en Firebird entonces te resultará bastante fácil hallar el valor máximo que puedes almacenar en esas columnas. Si tienes dudas, puedes consultar los dos artículos cuyos enlaces encontrarás más arriba.
Artículos relacionados
Determinando la precisión y la escala de una columna NUMERIC
georgeonil
May 25, 2014 @ 23:35:33
jajaja culpable
Pase de clipper a visual foxpro y ahora estoy pasando un pequeño sistemita a firebird con apoyo de visual foxpro
y estoy cometiendo ese error.
Gracias por esta publicación
Saludos.
wrov
May 26, 2014 @ 00:58:45
De nada, son pequeños errores de concepto que pueden ocasionarnos grandes molestias, por eso es mejor comprenderlos bien para no cometer equivocaciones.
Saludos.
Walter.
Ramiro
May 28, 2014 @ 12:44:22
Antes que nada felicidades por tu blog.
Tengo una pregunta referente a un SQL para sacar unos saldos de clientes este es el problema:
tclientes, tmovs
de clientes requiero: id, nombre
de tmovs: fechaultmov, saldo. Pero solo necesito 1 registro el ultimo y esta tabla contiene todos los movs del cliente. Si solo fuera el saldo no tengo problemas con el sql select pero requiero tambien la fecha y no se como configurar este sql en particular.
Cualquier ayuda, de antemano gracias.
wrov
May 28, 2014 @ 14:22:20
Hola Ramiro
Si solamente requieres el último registro entonces ordena tu tabla en forma descendente por fechas y recupera el primer registro. Como la tabla está ordenada en forma descendente el primer registro siempre será el más nuevo.
Saludos.
Walter.
Saray
May 29, 2014 @ 11:19:36
Buenas tardes,
Ante todo quería felicitarte por el blog y por la excelente labor divulgativa del firebird que haces en él.
Me gustaría saber si me podrías aclarar este tema sobre la configuración de los campos: quiero crear un campo precio cuyo tamaño máximo de enteros sea 10 y de decimales 6, en total 16 cifras significativas.
Lo he declarado como NUMERIC(18,6) (¿podría hacerlo también como NUMERIC(16,6)?), el caso es que al hacer una prueba e intentar introducir el valor máximo de 9999999999.999999 en la tabla se está guardando
9999999999.999998, lo está redondeando y no entiendo porqué.
Ejecuto desde el FlameRobin la siguiente instrucción:
UPDATE TIPODATOS SET PRECIOS=9999999999.999999
Cuando hago una SELECT de TIPODATOS en el campo PRECIO aparece como sexto decimal el número 8, no me da ningún error.
Gracias por tu ayuda,
Saray
wrov
May 29, 2014 @ 11:47:16
Gracias por las felicitaciones.
Lo que sucede es que cuando la precisión es 10 ó más se guarda internamente como un BIGINT. Y cuando se guarda como un BIGINT pueden ocurrir esos pequeños errores de redondeo.
Saludos.
Walter.