Usando un cursor con parámetros

Deja un comentario

En este artículo ya habíamos visto como usar cursores, y lo útiles que pueden ser:

https://firebird21.wordpress.com/2013/06/02/usando-cursores/

Ahora veremos un ejemplo donde el cursor tiene condiciones que vienen como parámetros de entrada del stored procedure.

CREATE PROCEDURE CURSOR_1(
   tnCodSuc TYPE OF COLUMN CLIENTES.CLI_CODSUC,
   tnIdent1 TYPE OF COLUMN CLIENTES.CLI_IDENTI,
   tnIdent2 TYPE OF COLUMN CLIENTES.CLI_IDENTI)
   RETURNS(
      ftnIdenti INTEGER,
      ftcNombre VARCHAR(40))
AS
   DECLARE VARIABLE lcContinuar CHAR(1);
   DECLARE VARIABLE MiCursor CURSOR FOR (
                                         SELECT
                                            CLI_IDENTI,
                                            CLI_NOMBRE
                                         FROM
                                            CLIENTES
                                         WHERE
                                            CLI_CODSUC = :tnCodSuc AND
                                            CLI_IDENTI BETWEEN :tnIdent1 AND :tnIdent2);
BEGIN

   OPEN MiCursor; /* Se abre el cursor */

   lcContinuar = 'S';

   WHILE (lcContinuar = 'S') DO BEGIN
      FETCH                             /* extrae una fila */
         MiCursor
      INTO
         :ftnIdenti,
         :ftcNombre;
      IF (ROW_COUNT = 1) THEN BEGIN     /* si ROW_COUNT = 1, se leyó una fila */
         /* Aquí se puede realizar algún proceso con los datos */
         SUSPEND;
      END ELSE
         lcContinuar = 'N';             /* Si ROW_COUNT = 0, ya no hay más filas */
   END

   CLOSE MiCursor; /* Se cierra el cursor */

END;

Como puedes ver, este stored procedure tiene 3 parámetros de entrada:

  • el código de la Sucursal
  • el identificador del primer cliente que nos interesa
  • el identificador del último cliente que nos interesa

y por lo tanto en el cursor tendremos los datos de los clientes que pertenecen a esa sucursal y cuyos identificadores están dentro del rango.

Artículos relacionados:

Usando cursores

El índice del blog Firebird21

Hallando los montos totales comprados cada mes

Deja un comentario

A veces podemos necesitar conocer los montos totales que se han comprado en cada mes del año, con los nombres de los respectivos meses y mostrando cero en los meses que no se hicieron compras.

La intención es que además del monto total comprado también se muestre el nombre del mes. Y si durante un mes no se hicieron compras (quizás porque estamos en Mayo y por lo tanto aún no se hicieron compras en Junio, Julio, Agosto, etc.) que se muestre cero en esos casos.

Este pequeño stored procedure hará la tarea:

CREATE PROCEDURE COMPRAS_POR_MES(
   tnAno SMALLINT,
   tnCodSuc TYPE OF COLUMN MOVIMCAB.MVC_CODSUC)
   RETURNS(
      ftcNombreMes TYPE OF D_NOMBRE10 COLLATE ISO8859_1,
      ftnMonto TYPE OF COLUMN MOVIMCAB.MVC_TOTALX)
AS
   DECLARE VARIABLE lnI SMALLINT;
BEGIN

   lnI = 1;

   WHILE (lnI <= 12) DO BEGIN
      ftcNombreMes = DECODE(lnI,  1, 'ENE',  2, 'FEB',  3, 'MAR',  4, 'ABR',  5, 'MAY',  6, 'JUN',
                                  7, 'JUL',  8, 'AGO',  9, 'SEP', 10, 'OCT', 11, 'NOV', 12, 'DIC');
      ftnMonto = (SELECT
                     SUM(MVC_TOTALX)
                  FROM
                     MOVIMCAB
                  WHERE
                     MVC_CODSUC = :tnCodSuc AND
                     MVC_TIPMOV = 'ECM' AND
                     EXTRACT(MONTH FROM MVC_FECHAX) = :lnI AND
                     EXTRACT(YEAR FROM MVC_FECHAX) = :tnAno);
      ftnMonto = COALESCE(ftnMonto, 0);
      SUSPEND;
      lnI = lnI + 1;
   END

END;

El parámetro tnAno especifica el año que nos interesa y el parámetro tnCodSuc especifica el número de la Sucursal. La columna MVC_TIPMOV guarda el tipo de movimiento ocurrido (donde ‘ECM’ significa: “entrada al stock por compra”) y la columna MVC_TOTALX es una columna computada para conocer rápidamente el monto total de cada compra.

Usamos la función COALESCE() para no tener valores NULL.

Después de ejecutar el stored procedure COMPRAS_POR_MES podríamos tener algo así:

SELECT
   *
FROM
   COMPRAS_POR_MES(2013, 0)

COMPRAS1

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

Desde luego que podríamos usar la misma técnica para hallar las ventas totales de cada mes, las cobranzas, los pagos, etc.

Artículo relacionado:

El índice del blog Firebird21