Algo que suele costarles entender a quienes empiezan a utilizar Firebird son estos tipos de columnas: NUMERIC y DECIMAL, así que trataré de ponerle un poco de luz al asunto.

1. El Firebird almacena internamente a las columnas NUMERIC y a las columnas DECIMAL como números enteros

2. Eso significa que escribas lo que escribas en esas columnas, internamente se guardará como un número entero

3. La cantidad de valores numéricos distintos que se pueden almacenar en un tipo de columna depende de la cantidad de bytes que le corresponda a ese tipo de columna. Un byte = 256 valores distintos, 2 bytes = 65.536 valores distintos, 3 bytes = 16.777.216 valores distintos, 4 bytes = 4.294.967.296 valores distintos y así sucesivamente.

4. SMALLINT usa 2 bytes, INTEGER usa 4 bytes, INT64 usa 8 bytes

5. La mitad de esos valores son positivos y la otra mitad son negativos, por lo tanto: SMALLINT (de -32.768 a +32.767), INTEGER (de -2.147.483.648 a +2.147.483.647), INT64 (de -9.223.372.036.854.775.808 a +9.223.372.036.854.775.807)

6. Cuando se define una columna como NUMERIC o como DECIMAL se toman en consideración dos parámetros: precisión (p) y escala (s). Se representan como NUMERIC(p, s) y DECIMAL(p, s)

7. La precisión (abreviada como “p”) es la cantidad de dígitos que tiene la parte entera del número. La escala (abreviada como “s”, inicial del inglés “scale”) es la cantidad de dígitos que hay en la parte decimal del número. Por ejemplo, NUMERIC(7, 3) significa que hay 7 dígitos en la parte entera del número y 3 dígitos en la parte decimal del número: eeeeeee.ddd

8. La cantidad de bytes que el Firebird utiliza para guardar una columna NUMERIC o DECIMAL depende de la precisión elegida, aquí no importa la escala, solamente importa la precisión:

Precisión  Tipo entero utilizado                                Rango de valores posibles
  1 a  4   SMALLINT para NUMERIC                                        -32.768 a +32.767
           INTEGER para DECIMAL                           -2.147.483.648 a +2.147.483.647
  5 a  9   INTEGER                                        -2.147.483.648 a +2.147.483.647
 10 a 18   INT64                  -9.223.372.036.854.775.808 a +9.223.372.036.854.775.807

9. Cuando se especifica una escala (s) se divide por 10 elevado a la escala elegida. Por ejemplo NUMERIC(4, 1) puede almacenar números desde (-3.276,8 hasta +3.276,7). NUMERIC (4, 2) puede almacenar números desde (-327,68 hasta +327,67). En el primer caso se dividió por 10 porque la escala era 1 y en el segundo caso se dividió por 100 porque la escala era 2. Si la escala es 3 se divide por 1.000 y así sucesivamente.

10. El Firebird no permite disminuir la precisión de una columna (para aumentar la precisión no hay problema). Por ejemplo, si tenemos una columna definida como NUMERIC(9, 2) y la queremos cambiar a NUMERIC(9, 3) se enojará y no nos permitirá hacer el cambio. ¿Por qué eso? porque cuando es NUMERIC(9, 2) la parte entera tiene 7 dígitos (9 – 2 = 7), en cambio cuando es NUMERIC(9, 3) la parte entera tiene 6 dígitos (9 – 3 = 6). Y aunque nosotros estemos seguros que todos los números cabrán cómodamente en la nueva definición, el Firebird no verifica eso y simplemente no nos permite disminuir la precisión.

11. El punto 10. se puede solucionar de dos formas:

a. Creamos una nueva columna como NUMERIC(9, 3), copiamos todos los valores de la columna NUMERIC(9, 2) a la columna NUMERIC(9, 3) que acabamos de crear, borramos la columna NUMERIC(9, 2), renombramos a la columna NUMERIC(9, 3)

b. Cambiamos la definición de la columna NUMERIC(9, 2) a NUMERIC(10, 3). Como la precisión seguirá siendo 7 (9 – 2 = 7 y también 10 – 3 = 7), el Firebird no se enojará con nosotros

12. Cuando definimos a una columna como NUMERIC(p, s) o como DECIMAL(p, s) debemos tener en cuenta la tabla de arriba para estar seguros de que todos los valores posibles cabrán en nuestra definición. Por ejemplo, definir el PRECIO como siendo NUMERIC(9, 4) puede ser insuficiente en muchos casos porque el precio máximo que podremos almacenar es 214.748,3648. Dependiendo de lo que estemos vendiendo, podría quedarse corto.