Aumentando la velocidad de NBACKUP

2 comentarios

Como recordarás, Firebird viene con dos programas que te permiten hacer backups de las bases de datos:

  • GBAK.EXE
  • NBACKUP.EXE

Ambos tienen sus ventajas y sus desventajas, y es por eso que existen dos. Si uno de ellos fuera mejor en todo entonces el otro no existiría, no tendría razón de ser.

Cuando se hace el backup con el programa NBACKUP.EXE se puede usar el parámetro -D para aumentar la velocidad en que se realiza el backup.

¿Qué significado tiene el parámetro -D?

Habilita o deshabilita la copia directa, es decir sin la intervención del caché del sistema de archivos del sistema operativo.

A veces, escribiendo -D ON se consigue una mayor velocidad y a veces escribiendo -D OFF se consigue una mayor velocidad.

¿Qué se debe escribir?

NBACKUP -U SYSDBA -P masterkey -B 0 MiBaseDatos.FDB MiBackup.NBK -D ON

Reemplazando por supuesto el ON por el OFF para probar la forma alternativa

¿Cómo saber cuál opción es mejor?

Probando de ambas formas y midiendo los tiempos empleados en realizar los respectivos backups.

En unas pruebas que hizo el autor de este blog con una Base de Datos de 580 Mb, los resultados fueron:

  • con el parámetro -D ON, 27 segundos
  • con el parámetro -D OFF, 12 segundos

En ese caso evidentemente -D OFF fue mejor, pero no siempre será así, dependiendo de tu Sistema Operativo y del tamaño de tu Base de Datos eso podría variar. Entonces, hay que probar.

Conclusión:

Si haces backups por intermedio del programa NBACKUP.EXE entonces deberías probar con el parámetro -D para descubrir si poniéndolo en ON o en OFF se obtienen mejores resultados.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

 

Se liberó Firebird 2.5.3

2 comentarios

La última versión de Firebird ha sido liberada, se trata de la 2.5.3, que ha corregido algunos bugs y también tiene algunas pequeñas mejoras. Como siempre, se recomienda su utilización porque es mejor que las anteriores, por eso justamente existe, para mejorar lo que ya se tenía.

Puede ser descargada desde aquí:

http://www.firebirdsql.org/en/firebird-2-5-3/

Y como es habitual se recomienda leer la “Release Notes” que vienen incluidas, allí se detalla lo que se corrigió y lo que se mejoró.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

 

Especificando el archivo FIREBIRD.MSG que queremos usar

Deja un comentario

Este artículo está basado en el artículo:

http://www.firebase.com.br/fb/artigo.php?id=2644

Cuando instalamos al Firebird se copia en el disco duro un archivo llamado FIREBIRD.MSG que contiene los mensajes que mostrará el propio Servidor del Firebird y también algunos de los programas utilitarios que vienen incluidos en la instalación, tales como el GBAK.EXE, el GFIX.EXE, etc.

Si en la computadora hemos instalado solamente una versión del Firebird entonces no tendremos problema, siempre veremos los mensajes correctos, pero si hemos instalado al Firebird más de una vez entonces podremos encontrarnos con un mensaje similar al siguiente:

can't format message...

gbak: writing data for table @1
gbak:@1 records written

¿Qué significa eso?

Que no puede encontrar al archivo FIREBIRD.MSG o que el archivo FIREBIRD.MSG que encontró no corresponde a la versión del Firebird que se está ejecutando.

¿Cómo lo resolvemos?

Configurando a una variable de ambiente llamada FIREBIRD_MSG con la ruta completa al archivo FIREBIRD.MSG que queremos usar, así:

MSG1

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

Y a continuación podemos llamar al utilitario GBAK.EXE, al utilitario GFIX.EXE, etc. y todos los mensajes aparecerán correctamente formateados.

Alternativa:

La forma de resolverlo mostrada arriba siempre funcionará pero si queremos que funcione sin necesidad de configurar a la variable de ambiente FIREBIRD_MSG deberemos hacer lo siguiente:

  • Copiar el archivo FIREBIRD.MSG en la carpeta superior de donde se encuentra el archivo FBCLIENT.DLL

En Windows lo aconsejable es que el archivo FBCLIENT.DLL se encuentre en la misma carpeta en la cual se encuentra el .EXE de nuestra aplicación.

Por lo tanto, en la misma carpeta donde se encuentra nuestro ejecutable CONTA.EXE, STOCK.EXE, VENTAS.EXE, SUELDOS.EXE, etc. copiamos al archivo FBCLIENT.DLL y en la carpeta superior copiamos al archivo FIREBIRD.MSG

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

 

Algunas preguntas y respuestas sobre el SQL de Firebird

7 comentarios

1. ¿Cómo creo una nueva Base de Datos?

Usando el comando CREATE DATABASE

2. ¿Cómo creo una tabla?

Usando el comando CREATE TABLE

3. ¿Qué es un dominio?

Un tipo de datos que yo puedo definir, usando para ello un tipo de datos ya existente

4. ¿Cómo le agrego datos a una tabla?

Con el comando INSERT o con el comando UPDATE OR INSERT

5. ¿Cómo modifico los datos de una tabla?

Con el comando UPDATE o con el comando UPDATE OR INSERT

6. ¿Cómo borro filas de una tabla?

Con el comando DELETE

7. ¿Cómo puedo conocer el contenido de una tabla?

Con el comando SELECT

8. ¿Cómo puedo combinar datos de dos o más tablas?

Con las cláusulas JOIN y UNION

9. ¿Una tabla puede combinarse con sí misma?

10. ¿Cómo puedo mostrar los resultados de un SELECT ordenados?

Con la cláusula ORDER BY

11. ¿Qué debo hacer para buscar un dato dentro de una tabla?

Usar la cláusula WHERE o la cláusula HAVING

12. ¿Cómo puedo totalizar los valores de una columna de una tabla?

Usando la función agregada SUM().

 13. ¿Cómo hago para agrupar datos similares?

Usando la cláusula GROUP BY

14. ¿Qué es una clave primaria o Primary Key?

Un valor único que sirve para identificar a cada fila de una tabla, las Primary Key no pueden repetirse ni tener valores NULL

15. ¿Qué es un valor NULL?

Un valor desconocido. NULL no es lo mismo que una cadena vacía ni una fecha vacía ni un cero. NULL significa “desconocido” o sea que no se tiene la menor idea de cual es su valor.

16. ¿Qué es una clave foránea o Foreign Key?

Un valor que sirve para relacionar a dos tablas entre sí.

17. ¿Qué es una clave única o Unique Key?

Un valor que no puede estar repetido.

18. ¿Qué es una restricción check?

Una condición que debe cumplirse para que una fila pueda ser insertada o actualizada

19. ¿Qué es un stored procedure?

Una rutina que se ejecuta cuando el desarrollador de la Base de Datos quiere que se ejecute

20. ¿Qué es un trigger?

Una rutina que se ejecuta automáticamente cuando se cumple una condición

21. ¿Cómo puedo restringir el acceso al contenido de la Base de Datos?

Otorgándoles derechos, también llamados permisos o privilegios, a las personas autorizadas. Si muchas personas compartirán los mismos derechos entonces suele ser conveniente crear roles. Un rol es un grupo de usuarios que tienen exactamente los mismos derechos.

Artículos relacionados

El índice del blog Firebird21

El foro del blog Firebird21

 

Sentencias simples y sentencias compuestas

2 comentarios

Cuando escribimos un stored procedure o un trigger podemos usar sentencias simples o sentencias compuestas.

Si la sentencia es simple una sola línea es ejecutada, si la sentencia es compuesta muchas líneas pueden ser ejecutadas.

Ejemplo 1. Una sentencia simple en un IF()

IF (MiCondición) THEN
   MiSentencia;

-- Esta línea ya no está dentro del IF()
-- Y esta línea tampoco está dentro del IF()

En este caso solamente se ejecutará la línea MiSentencia si MiCondición es verdadera. Las que están a continuación se ejecutarán siempre ¿por qué? porque no están incluidas en el IF().

Ejemplo 2. Una sentencia compuesta en un IF()

IF (MiCondición) THEN BEGIN
   MiSentencia1;
   MiSentencia2;
   MiSentencia3;
   --
   MiSentencian;
END
-- Esta línea ya no está dentro del IF()
-- Y esta línea tampoco está dentro del IF()

En este caso la sentencia ya no es simple sino compuesta ¿y cómo sabemos eso? Porque el Firebird trata a todas las sentencias escritas entre el BEGIN y el END como pertenecientes al IF(), hay varias sentencias allí y todas ellas serán ejecutadas si MiCondición es verdadera.

Ejemplo 3. Una sentencia compuesta y una sentencia simple en un IF()

IF (MiCondición) THEN BEGIN
   MiSentencia1;
   MiSentencia2;
   MiSentencia3;
   --
   MiSentencian;
END ELSE
   MiSentenciax;
-- Esta línea ya no está dentro del ELSE
-- Y esta línea tampoco está dentro del ELSE

En este caso, si MiCondición es verdadera se ejecutará la sentencia compuesta que está entre el BEGIN y el END pero si MiCondición es falsa entonces se ejecutará la sentencia simple que está a continuación del ELSE.

Ejemplo 4. Dos sentencias compuestas en un IF()

IF (MiCondición) THEN BEGIN
   MiSentencia1;
   MiSentencia2;
   MiSentencia3;
   --
   MiSentencian;
END ELSE BEGIN
   MiSentenciax;
   MiSentenciay;
   MiSentenciaz;
   --
   MiSentenciam;
END
-- Esta línea ya no está dentro del ELSE
-- Y esta línea tampoco está dentro del ELSE

En este caso hay un BEGIN … END después del THEN y hay otro BEGIN … END después del ELSE. ¿Qué significa eso? Que si MiCondición es verdadera se ejecutarán todas las líneas que están en el primer BEGIN … END y en cambio si MiCondición es falsa se ejecutarán todas las líneas que están en el segundo BEGIN … END.

Ejemplo 5. Una sentencia simple en un ciclo WHILE()

WHILE (MiCondición) DO
   MiSentencia;
-- Esta línea ya no está dentro del WHILE
-- Y esta línea tampoco está dentro del WHILE

Aquí, mientras MiCondición sea verdadera se ejecutará MiSentencia.

Ejemplo 6. Una sentencia compuesta en un ciclo WHILE()

WHILE (MiCondición) DO BEGIN
   MiSentencia1;
   MiSentencia2;
   MiSentencia3;
   --
   MiSentencian;
END
-- Esta línea ya no está dentro del WHILE
-- Y esta línea tampoco está dentro del WHILE

Ahora en el ciclo WHILE() se está usando una sentencia compuesta. Todas las líneas que hayamos escrito entre el BEGIN y el END se ejecutarán mientras MiCondición sea verdadera.

Ejemplo 7. Una sentencia simple en un FOR SELECT

FOR SELECT
   MiColumna
FROM
   MiTabla
INTO
   :MiVariable
DO
   MiSentencia;
-- Este línea ya no pertenece al FOR SELECT
-- Y esta línea tampoco

Solamente MiSentencia se ejecutará porque se trata de una sentencia simple y por lo tanto solamente la línea que sigue al DO se ejecuta.

Ejemplo 8. Una sentencia compuesta en un FOR SELECT

FOR SELECT
   MiColumna
FROM
   MiTabla
INTO
   :MiVariable
DO BEGIN
   MiSentencia1;
   MiSentencia2;
   MiSentencia3;
   --
   MiSentencian;
END
-- Este línea ya no pertenece al FOR SELECT
-- Y esta línea tampoco

Después del DO hay un BEGIN … END, eso nos indica que se trata de una sentencia compuesta y por lo tanto todas las líneas que se encuentran dentro del BEGIN … END serán ejecutadas.

Conclusión:

Al igual que en Pascal, C, y otros lenguajes en Firebird podemos usar sentencias simples o sentencias compuestas. Las sentencias compuestas empiezan con un BEGIN y finalizan con un END y todo lo que esté escrito entre esas dos palabras se trata como una unidad.

Si no usamos BEGIN … END entonces siempre y en todos los casos la sentencia será simple. Para que sea compuesta sí o sí deberemos rodearla por las palabras BEGIN … END

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

 

Un stored procedure para borrar filas de cualquier tabla

Deja un comentario

Como seguramente sabrás, lo recomendable es que todas las operaciones que realices en una tabla (INSERT, UPDATE, DELETE, SELECT) las hagas a través de stored procedures o de vistas.

¿Por qué?

Porque de esa manera el procesamiento es más rápido (el Servidor siempre es más rápido que el Cliente) y te aseguras que la operación que deseas realizar esté sintácticamente correcta (si no lo está, no podrás compilar el stored procedure o la vista).

Pero supongamos que en tu Base de Datos tienes 100 tablas. ¿Necesitas escribir un stored procedure para cada tabla para borrar las filas de esa tabla?

No, no lo necesitas, y lo mejor es que no lo hagas. Para casos así lo mejor es parametrizar es decir enviar como parámetros de entrada los datos cambiantes. Entonces, escribiendo un solo stored procedure podrás borrar las filas de cualquiera de esas tablas.

CREATE PROCEDURE SP_BORRAR_FILAS(
   tcNombreTabla VARCHAR(32),
   tcCondicion   VARCHAR(1024))
AS
   DECLARE VARIABLE lcComando VARCHAR(1024);
BEGIN

   lcComando = 'DELETE FROM ' ||
                   tcNombreTabla ||
               IIF(CHAR_LENGTH(TRIM(tcCondicion)) > 0, ' WHERE ' || '' || tcCondicion || '', '');

   EXECUTE STATEMENT :lcComando;

END;

Este stored procedure recibe dos parámetros de entrada: el nombre de la tabla y la condición para borrar filas. Y nos servirá para borrar las filas de cualquier tabla y con cualquier condición de borrado.

Ejemplo 1. Para borrar el producto cuyo identificador es 597

EXECUTE PROCEDURE SP_BORRAR_FILAS('PRODUCTOS', 'PRD_IDENTI=597');

El producto cuyo identificador es 597 será borrado (siempre y cuando no hubiera alguna restricción Foreign Key que lo impida, claro)

Ejemplo 2. Para borrar el Banco cuyo nombre es CITIBANK

EXECUTE PROCEDURE SP_BORRAR_FILAS('BANCOS', 'BAN_NOMBRE = ''CITIBANK''');

En este caso fíjate en los apóstrofos (comillas simples) que rodean a la palabra CITIBANK. Como dentro de nuestra condición queremos emplear apóstrofos (comillas simples) entonces debemos escribirlos duplicados.

Ejemplo 3. Para borrar todas las cobranzas realizadas en el mes de enero de 2014

EXECUTE PROCEDURE SP_BORRAR_FILAS('COBRANZAS', 'EXTRACT(MONTH FROM COB_FECHAX) = 1 AND EXTRACT(YEAR FROM COB_FECHAX) = 2014');

En este caso la condición es más complicada porque involucra al operador AND. Pero el stored procedure sigue funcionando perfectamente, si la condición está bien escrita entonces se borrarán las filas que se desean borrar.

Ejemplo 4. Para borrar todas las filas de una tabla

EXECUTE PROCEDURE SP_BORRAR_FILAS('TEMP', '');

Aquí, se borraron todas las filas de una tabla llamada TEMP. Como no se estableció una condición para borrar filas eso significa que se quiere borrarlas a todas.

¡¡¡MUCHO CUIDADO CON ESTO!!!

Recuerda que no poner una condición de borrado significa borrar todas las filas de la tabla.

Conclusión:

Si parametrizamos nuestros stored procedures entonces tendremos varias ventajas:

  1. Estaremos 100% seguros de que siempre funcionará bien
  2. No tendremos que perder tiempo verificando si funciona bien
  3. Escribiremos mucho menos, porque un solo stored procedure parametrizado puede hacer el mismo trabajo que muchos stored procedures no parametrizados

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21