Hallar los movimientos ocurridos entre dos fechas (otro método)

5 comentarios

En este artículo ya habíamos visto un método para hallar todos los movimientos (compras, ventas, cobranzas, pagos, etc.) que ocurrieron entre dos fechas dadas, y si en una fecha no hubo movimientos entonces mostrarla igual pero con un total de cero.

https://firebird21.wordpress.com/2014/04/29/hallando-todas-las-ventas-entre-dos-fechas-dadas/

Ahora, veremos otro método con el cual podremos obtener los mismos resultados, gracias a la colaboración de Claudio Martín.

Aquí, lo que haremos será crear un stored procedure seleccionable que nos devolverá todas las fechas de un rango dado, y luego cuando las necesitemos mediante un LEFT JOIN o un RIGHT JOIN las obtendremos.

Este método tiene la ventaja de que el stored procedure seleccionable que escribimos es uno solo y lo podemos utilizar en multitud de ocasiones diferentes, todas las veces que necesitemos un rango de fechas.


CREATE PROCEDURE RANGO_FECHAS(
      tdFecIni DATE,
      tdFecFin DATE)
   RETURNS(
      ftdFecha DATE)
AS
   DECLARE VARIABLE ldFecha DATE;
BEGIN

   ldFecha = tdFecIni;

   WHILE (ldFecha <= tdFecFin) DO BEGIN
      ftdFecha = ldFecha;
      SUSPEND;
      ldFecha = ldFecha + 1;
   END

END;

Entonces, usando la misma tabla que en el artículo anterior, escribiríamos:

SELECT
   R.ftdFecha,
   SUM(COALESCE(M.MVC_TOTALX, 0)) AS TOTAL_VENTAS_DIA
FROM
   RANGO_FECHAS('01/01/2014', '01/07/2014') R
LEFT JOIN
   MOVIMCAB M
      ON R.ftdFecha = M.MVC_FECHAX
GROUP BY
   R.ftdFecha

Y obtendríamos este resultado:

VENTAS1

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

El cual, como puedes verificar, es exactamente igual al obtenido con el otro método. Pero la ventaja de este nuevo método es que el stored procedure seleccionable podemos usarlo siempre que necesitemos obtener todas las fechas de un rango dado.

 Conclusión:

Una de las muchas cosas buenas que tiene el Firebird es que nos permite obtener los mismos resultados usando métodos diferentes, queda a nuestro criterio elegir el que nos parece más conveniente para cada situación particular.

En este caso, podemos tener un stored procedure que cuando las necesitemos nos devolverá todas las fechas de un rango, para ello simplemente lo juntamos mediante LEFT JOIN o RIGHT JOIN a la otra tabla y listo, ya está.

Artículos relacionados:

Hallando todas las ventas entre dos fechas dadas

Entendiendo a los Stored Procedures

El índice del blog Firebird21

 

Anuncios

Generando códigos dependientes

3 comentarios

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/