Poder tener columnas computadas es una característica muy buena que tiene el Firebird, ya que nos permite tener una columna “virtual”, una columna a la cual nunca se le insertan datos sino que su contenido es calculado (o computado) según el contenido de otra u otras columnas previamente definidas.

Como esta característica no existe en otros motores SQL entonces puede ser de interés mostrar algunos ejemplos de uso.

Ejemplo 1. Mostrando apellidos y nombres

Si has leído algo sobre normalización de tablas entonces recordarás que en una sola columna no deberían encontrarse dos o más datos que significan cosas distintas. Es decir, guardar en una sola columna los apellidos y también los nombres está mal, es incorrecto, deberían guardarse en columnas distintas. Ok, se guardan en columnas distintas, pero al mostrarlos queremos que aparezcan siempre con el mismo formato: los apellidos, una coma, y los nombres. Usando columnas computadas es muy fácil:

CREATE TABLE VENDEDORES (
   VEN_IDENTI D_IDENTIFICADOR NOT NULL,
   VEN_NOMBRE D_NOMBRE20,
   VEN_APELLD D_NOMBRE20,
   VEN_APENOM COMPUTED BY (TRIM(VEN_APELLD) || ', ' || VEN_NOMBRE));

En este caso nuestra tabla de VENDEDORES tiene una columna para guardar los nombres, otra columna para guardar los apellidos, y una columna computada para mostrarlos a ambos.

COMPUTADAS1

Captura 1. Si haces clic en la imagen la verás más grande

Los usuarios solamente pueden guardar datos en las columnas VEN_NOMBRE y VEN_APELLD, en la columna VEN_APENOM no pueden hacerlo. Su contenido es calculado (computado) automáticamente por el Firebird.

Por supuesto que en nuestros SELECTs podemos usar cualesquiera de esas columnas.

Ejemplo 2. Mostrando el total vendido de cada producto

CREATE TABLE MOVIMDET (
   MOV_IDENTI D_IDENTIFICADOR NOT NULL,
   MOV_IDECAB D_IDENTIFICADOR,
   MOV_IDEPRD D_IDENTIFICADOR,
   MOV_CANTID D_CANTIDAD,
   MOV_PRECIO D_PRECIO,
   MOV_TOTALX COMPUTED BY (MOV_CANTID * MOV_PRECIO));

En este caso guardamos en la tabla MOVIMDET el detalle de las ventas realizadas. Tenemos una columna para guardar la cantidad vendida, otra columna para guardar el precio unitario y una columna computada para mostrar el importe vendido de cada producto.

COMPUTADAS2

Captura 2. Si haces clic en la imagen la verás más grande

En la columna MOV_TOTALX tenemos el total vendido de cada producto, ese valor lo halla automáticamente el Firebird, nosotros no necesitamos calcularlo cada vez que lo necesitemos porque ya el Firebird se encargó de calcularlo para nosotros.

Ejemplo 3. Mostrando la bonificación familiar

En Paraguay (donde reside el autor de este blog) a los empleados se les paga un adicional del 5% por cada hijo menor de 18 años que tienen. Entonces nuestra tabla de EMPLEADOS podría ser similar a esta:

CREATE TABLE EMPLEADOS (
   EMP_CODSUC D_CODIGOSUCURSAL NOT NULL,
   EMP_IDENTI D_IDENTIFICADOR NOT NULL,
   EMP_NOMBRE D_NOMBRE20,
   EMP_APELLD D_NOMBRE20,
   EMP_SALBAS D_PRECIO2,
   EMP_APENOM COMPUTED BY (TRIM(EMP_APELLD) || ', ' || EMP_NOMBRE),
   EMP_CANHIJ COMPUTED BY ((
      SELECT
         COUNT(*)
      FROM
         EMPLEADOSFAM
      WHERE
         EMF_CODSUC = EMP_CODSUC AND
         EMF_IDECAB = EMP_IDENTI AND
         EXTRACT(YEAR FROM CURRENT_DATE) -
         EXTRACT(YEAR FROM EMF_FECNAC) < 18
   )),
   EMP_BONFAM COMPUTED BY (EMP_SALBAS * EMP_CANHIJ * 5 / 100));

Como se puede ver aquí, en una columna computada también se puede usar un SELECT, pero en ese caso hay que escribir dos paréntesis, no solamente uno. Es lo que se hizo en la columna computada EMP_CANHIJ, donde queremos tener la cantidad de hijos menores de 18 años que tiene cada empleado. Los datos de los hijos (nombres, fechas de nacimiento, etc.) se guardan en otra tabla, cuyo nombre es EMPLEADOSFAM (familiares de los empleados).

COMPUTADAS3

Captura 3. Si haces clic en la imagen la verás más grande

COMPUTADAS4

Captura 4. Si haces clic en la imagen la verás más grande

En nuestra tabla de EMPLEADOS tenemos a dos personas, y como podemos ver estamos usando varias columnas computadas:

  • EMP_APENOM para mostrar los apellidos y nombres del empleado
  • EMP_CANHIJ para mostrar la cantidad de hijos menores de 18 años
  • EMP_BONFAM para mostrar la bonificación familiar que le corresponde al empleado

Relacionamos a ambas tablas mediante las columnas EMP_IDENTI (identificador del empleado) y EMF_IDECAB (identificador de la cabecera).

ADVERTENCIA:

Como hemos visto en el Ejemplo 3. se puede escribir un SELECT dentro de una columna COMPUTED BY pero eso no es recomendable hacerlo en tablas que tienen muchas filas porque por cada empleado se realizará el SELECT correspondiente y eso puede demorar mucho tiempo. En general para estos casos es preferible crear una vista. Usaríamos un SELECT dentro de una columna COMPUTED BY solamente cuando la tabla del SELECT (no la tabla principal, sino la tabla del SELECT) tiene pocas filas y usa un índice.

Artículos relacionados:

Columnas computadas

Usando un SELECT en una columna computada

Un truco para encontrar valores que pueden estar en varias columnas

Utilizando columnas computadas

El índice del blog Firebird21

El foro del blog Firebird21

Anuncios