Como seguramente sabes, usar SELECT COUNT(*) FROM MiTabla para conocer la cantidad de filas que tiene una tabla no es recomendable en tablas cuyas filas se cuentan por millones. El motivo es que el Firebird hace un recorrido secuencial a todas las filas de la tabla para hallar la cantidad de esas filas y por lo tanto en tablas grandes demora mucho tiempo en responder.

Una alternativa mucho mejor para conocer la cantidad de filas de cada tabla habíamos visto en este artículo:

https://firebird21.wordpress.com/2013/03/08/como-saber-rapidamente-la-cantidad-de-filas-que-tiene-una-tabla/

que funciona perfecto pues cada vez que se inserta o se borra una fila de una tabla la nueva cantidad de filas es guardada en la tabla RECCOUNT.

Esta es la estructura de la tabla RECCOUNT:

RECCOUNT1

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

Este es el trigger que actualiza a la tabla RECCOUNT cuando una nueva fila es insertada en la tabla BANCOS

CREATE TRIGGER AI_BANCOS FOR BANCOS
   ACTIVE AFTER INSERT
   POSITION 0
AS
   DECLARE VARIABLE lnCantidadFilas INTEGER;
BEGIN

   lnCantidadFilas = COALESCE((SELECT REC_CANTID FROM RECCOUNT WHERE REC_NOMBRE = 'BANCOS'), 0);

   UPDATE OR INSERT INTO RECCOUNT
            (REC_CODSUC, REC_NOMBRE, REC_CANTID)
     VALUES (NEW.BAN_CODSUC, 'BANCOS', :lnCantidadFilas + 1)
   MATCHING (REC_NOMBRE) ;

END;

Y este es el trigger que actualiza a la tabla RECCOUNT cuando una fila es borrada de la tabla BANCOS

CREATE TRIGGER AD_BANCOS FOR BANCOS
   ACTIVE AFTER DELETE
   POSITION 1
AS
   DECLARE VARIABLE lnCantidadFilas INTEGER;
BEGIN

   lnCantidadFilas = (SELECT REC_CANTID FROM RECCOUNT WHERE REC_NOMBRE = 'BANCOS');

   IF (lnCantidadFilas IS NOT NULL AND lnCantidadFilas > 0) THEN
      UPDATE
         RECCOUNT
      SET
         REC_CANTID = :lnCantidadFilas - 1
      WHERE
         REC_CODSUC = OLD.BAN_CODSUC AND
         REC_NOMBRE = 'BANCOS';

END;

Pero ¿y si la tabla involucrada ya tenía filas? en ese caso la cantidad de filas guardada en la tabla RECCOUNT no será la correcta porque los triggers empezarán a sumar y a restar desde el momento en que fueron agregados, ellos no saben cuantas filas tenía la tabla previamente. O sea, en tablas nuevas la cantidad de filas guardadas en la columna REC_CANTID de la tabla RECCOUNT será la correcta, pero en tablas que ya tenían filas, no.

Por eso, para actualizar la cantidad de filas de cada tabla escribí el siguiente stored procedure y así cuando los triggers actualicen la columna REC_CANTID estará guardada en esa columna la cantidad correcta de filas de cada tabla.

CREATE PROCEDURE SP_ACTUALIZAR_CANTIDAD_FILAS(
   tnCodSuc TYPE OF D_CODIGOSUCURSAL)
AS
   DECLARE VARIABLE lcNombreTabla   VARCHAR(32);
   DECLARE VARIABLE lnCantidadFilas INTEGER;
   DECLARE VARIABLE lcComando       VARCHAR(128);
BEGIN

   FOR
      SELECT
         RDB$RELATION_NAME
      FROM
         RDB$RELATIONS
      WHERE
         RDB$SYSTEM_FLAG = 0 AND
         RDB$RELATION_TYPE = 0
      ORDER BY
         RDB$RELATION_NAME
      INTO
         :lcNombreTabla
   DO BEGIN
      lcComando = 'SELECT COUNT(*) FROM ' || lcNombreTabla ;
      EXECUTE STATEMENT (lcComando) INTO :lnCantidadFilas ;
      UPDATE OR INSERT INTO RECCOUNT
               (REC_CODSUC, REC_NOMBRE , REC_CANTID)
        VALUES (:tnCodSuc , :lcNombreTabla, :lnCantidadFilas)
      MATCHING (REC_NOMBRE);
   END

END;

¿Qué hace este stored procedure?

  1. Halla el nombre de cada tabla del usuario. O sea que están excluidas las tablas del sistema y las vistas
  2. Usando la función COUNT(*) halla la cantidad de filas de cada tabla
  3. Si el nombre de la tabla ya existía en la tabla RECCOUNT entonces actualiza la cantidad de filas. Si no existía la tabla, la agrega

Como este stored procedure utiliza la función COUNT() para conocer la cantidad de filas de cada tabla, su ejecución puede demorar varios minutos así que … paciencia. Lo bueno es que deberás ejecutarlo una sola vez.

Artículos relacionados:

Nombres de todas las tablas

Como saber rápidamente la cantidad de filas que tiene una tabla

El índice del blog Firebird21

 

Anuncios