A veces podemos encontrarnos con la siguiente situación: debemos codificar a los ítems pero esos códigos deben empezar con algunos caracteres predeterminados.

O sea, podríamos tener esta clase de códigos: AAC00001, AAC00002, AAC00003, CAM00001, CAM00002, ESC00001, ESC00002, ESC00003, etc.

Como ves, algunos códigos empiezan con AAC, algunos con CAM, algunos con ESC, etc. Y en cada caso la numeración empieza con 00001.

Una solución es la siguiente:

  1. Creamos una tabla de categorías, donde guardaremos las iniciales de los códigos (AAC, CAM, ESC, etc.). Esa columna debe tener la restricción Unique Key para que no tengamos códigos repetidos
  2. Creamos una tabla de bienes, donde se guardarán los códigos dependientes (AAC00001, AAC00002, AAC00003, etc.)
  3. A la columna donde guardaremos el código del bien le agregamos la restricción Unique Key
  4. En la tabla de bienes, creamos un trigger que se encargará de generar el código dependiente

CODIGO1

(haciendo clic en la imagen la verás más grande)

En la imagen de arriba podemos ver la estructura de la tabla CATEGORIAS. La columna CAT_INICIA debe tener la restricción Unique Key para asegurarnos que no tengamos iniciales repetidas.

CODIGO2

(haciendo clic en la imagen la verás más grande)

 En la imagen de arriba podemos ver algunas filas de la tabla CATEGORIAS.

CODIGO3

(haciendo clic en la imagen la verás más grande)

En la imagen de arriba podemos ver la estructura de la tabla BIENES. Recuerda que la columna BIE_CODIGO debe estar declararada como Unique Key para que el Firebird nos impida tener dos códigos idénticos.

A continuación, creamos un trigger como el siguiente:

SET TERM ^ ;

CREATE TRIGGER BIENES_BI FOR BIENES
   ACTIVE BEFORE INSERT
   POSITION 1
AS
   DECLARE VARIABLE lcCodigo D_CHAR8;
   DECLARE VARIABLE lnNumero D_CANTIDAD;
   DECLARE VARIABLE lcInicia D_CHAR3;
BEGIN

   /* Primero, se halla el último código de esta categoría */
   FOR SELECT
      BIE_CODIGO
   FROM
      BIENES
   WHERE
      BIE_IDECAT = NEW.BIE_IDECAT
   ORDER BY
      BIE_CODIGO
   INTO
      :lcCodigo
   DO BEGIN
   END

   /* Si no se encontró, el número será 1. Si se encontró, será el siguiente */
   IF (lcCodigo IS NULL) THEN
      lnNumero = 1;
   ELSE
      lnNumero = CAST(RIGHT(lcCodigo, 5) AS INTEGER) + 1;

   /* Se obtienen los caracteres iniciales del código */
   lcInicia = (SELECT CAT_INICIA FROM CATEGORIAS WHERE CAT_IDENTI = NEW.BIE_IDECAT);

   /* Se forma el código del bien que se grabará en la tabla */
   NEW.BIE_CODIGO = lcInicia || LPAD(lnNumero, 5, '0');

END^

SET TERM ; ^

Luego de insertar algunas filas en la tabla de BIENES esto es lo que obtenemos:

CODIGO4

(haciendo clic en la imagen la verás más grande)

Los usuarios solamente introdujeron el Identificador de la Categoría y el Nombre del Bien. El Identificador del Bien y el Código del Bien (la columna BIE_CODIGO) fueron puestos automáticamente por los triggers.

Observaciones:

  • En este ejemplo los códigos de los bienes empiezan con 3 caracteres predeterminados, pero pueden ser 2, 4, 5, ó cualquier otra cantidad. Eso se determina en la columna CAT_INICIA de la tabla CATEGORIAS
  • En este ejemplo los números tienen 5 dígitos y por lo tanto pueden variar entre 00001 y 99999 pero se pueden usar 2 dígitos, 3 dígitos, 7 dígitos o cualquier otra cantidad. Eso se determina en la columna BIE_CODIGO de la tabla BIENES. Como en este ejemplo la columna CAT_INICIA tiene 3 caracteres y el número máximo que se quiere usar es 99999 entonces la columna BIE_CODIGO tiene 8 caracteres.
  • Si más de una persona están introduciendo bienes al mismo tiempo entonces puede ocurrir que generen el mismo código del bien. Para evitar que se  graben códigos duplicados es que se debe usar la restricción Unique Key en la columna BIE_CODIGO. La primera persona grabará sin problemas, pero la segunda no podrá grabar porque el código ya existe y deberá volver a presionar el botón “Grabar” para que se genere un nuevo código del bien y allí sí se grabarán sus datos (bueno, si tiene mala suerte otra persona ya generó ese mismo código y deberá presionar el botón “Grabar” nuevamente hasta que tenga éxito. Si esta es una situación frecuente lo más conveniente es que sea el programa el encargado de reintentar la grabación hasta conseguirla).

Artículos relacionados:

https://firebird21.wordpress.com/2013/03/29/cast/

https://firebird21.wordpress.com/2013/04/10/lpad/

https://firebird21.wordpress.com/2013/04/14/right/

https://firebird21.wordpress.com/2013/03/17/entendiendo-a-los-triggers/

Anuncios