Recientemente un cliente me pidió ayuda porque uno de sus campos numéricos pierde precisión con los decimales. Como me parece muy importante quiero aprovechar para aclarar conceptos, es algo complejo, pero voy a tratar de dejarlo lo más claro posible. Como sabemos tenemos varios tipos de datos que nos van a permitir almacenar números en SQL Server. Vamos a ir viendo uno a uno, pero antes tenemos que saber que significan una serie de conceptos. Los tipos de datos en SQL Server tienen 3 cualidades:
- PRECISIÓN: Cantidad máxima de dígitos que puede tener en total (entero + decimal).
- ESCALA: Cantidad máxima de dígitos después del decimal que puede tener.
- PRECISION_RADIX: Especifica la potencia en la que se expresa la precisión, admite los valores 2 o 10, luego profundizamos más sobre esto.
Ahora sí, los tipos de datos, partamos de esta imagen y vamos viendo en detalle:

Tipos de Datos: BIGINT, INT, SMALLINT y TINYINT
Estos tipos de datos se usan para almacenar datos numéricos exactos y enteros. NO ADMITEN DECIMALES. Tenemos que usar uno u otro en función de nuestras necesidades, aunque, siempre es recomendable el más pequeño posible para ahorrar espacio en disco y ganar rendimiento. Por ejemplo, para un valor de edad de una persona con un tinyint es más que suficiente (con el estado actual de la ciencia nadie va a vivir más de 255 años o no habría dinero para pagarle la pensión), pero para un ID de una tabla 255 posibles opciones se queda corto.
Tipos de Datos: DECIMAL y NUMERIC
Antes de seguir, vamos a aclarar una de las mayores dudas que tiene la gente en SQL Server: DECIMAL y NUMERIC son sinónimos, da igual cual uses, es lo mismo, no hay uno mejor, va a rendir igual, van a comportarse igual y cualquier otra cosa que podáis imaginar. ¿Claro esto? Vale genial, esta es la pregunta que más veces me han hecho desde que me dedico a las bases de datos y a partir de ahora al que me lo pregunte le mandaré a vosotros. Volviendo a lo nuestro, estos datos son numéricos con una precisión y una escala fija. La precisión máxima que pueden tener es de 38 y la escala puede ser desde 0 hasta la precisión que hayamos definido. El tamaño que ocupa en disco y por tanto su rendimiento dependerá de la precisión que definamos así que, como es lógico, tenemos que usar una precisión suficiente para almacenar lo que necesitamos, pero sin pasarnos.
Tipos de Datos: MONEY y SMALLMONEY
La teoría dice que son tipos de datos que usa SQL para almacenar valores monetarios, pero, permitidme ser muy claro en esto, es una GRANDISIMA MIERDA. No voy a decir más, os dejo una foto y al que vea usando datos de este tipo le cortaré las manos.
Nota: Ya sé lo que me vais a decir, que no se puede dividir dinero entre dinero, pero no lo uséis y os ahorraréis problemas.
Tipos de Datos: FLOAT Y REAL
Estos son tipos de datos numéricos y aproximados que se utilizan con datos numéricos de coma flotante. Para que nos entendamos son datos numéricos para operaciones científicas y no los vamos a usar para almacenar nuestros valores. Como máximo admiten hasta 15 dígitos el FLOAT y 7 el REAL, aunque en al consultar su precisión vemos 53 o 24 para estos tipos de datos, eso es el número de bits que almacena internamente. Lo importante aquí es que no son números exactos y cuando llegas a la precisión máxima va a redondear por lo que bajo ningún concepto deberíamos utilizarlos para almacenar nuestros valores numéricos. No tienen escala por defecto, admite tantos decimales como precisión tenga. Si os fijáis otra vez en la primera captura que os he puesto al principio, estos dos tipos de datos tienen un valor NUMERIC_PRECISION_RADIX distinto a los demás, esto es porque se almacenan en binario no en base decimal en la base de datos. Como esto está muy bien explicado en la Wikipedia y este post ya se ha alargado demasiado os dejo el enlace por si os interesa profundizar en el tema https://es.wikipedia.org/wiki/Coma_flotante.
Enhorabuena por haber llegado hasta aquí abajo, espero que hayáis aprendido tanto leyendo esto como yo me he desasnado escribiéndolo😝 Antes de cerrar os dejo un apunte más copiado directamente de la web de SQL y ya no os robo más tiempo.
CONVERISIONES DE DATOS
Al convertir de decimal o numeric a float o real se puede provocar una pérdida de precisión. Al convertir de int, smallint, tinyint, float, real, money o smallmoney a decimal o numeric se puede provocar un desbordamiento. De forma predeterminada, SQL Server usa el redondeo cuando convierte un número a un valor decimal o numeric con una precisión y una escala inferiores. Y a la inversa, si la opción SET ARITHABORT está establecida en ON, SQL Server genera un error cuando se produce un desbordamiento. La pérdida de únicamente precisión y escala no es suficiente para generar un error.


[…] todos los posibles números. Si recordáis el primer artículo de este blog hablamos sobre los tipos de datos numéricos y vimos cual era el mejor para cada situación, en nuestro caso el que mejor se adapta es el int. […]
[…] cuando trabajamos con datos es la gestión de las fechas y horas. Al igual que nos pasaba con los datos numéricos, elegir el tipo de datos de fecha y/o hora correcto es de vital importancia y no debe ser ignorado. […]