Error al ejecutar GSEC

5 comentarios

Como seguramente sabes, el programa GSEC.EXE se utiliza para agregar usuarios, cambiar datos de los usuarios, eliminar usuarios y ver cuales son los usuarios admitidos.

Pero si tienes más de una instancia del Firebird instalada entonces a veces podrías ver una pantalla de error similar a la siguiente:

GSEC1

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

¿Qué significa ese error número 335545106?

Que no puede abrir la Base de Datos en la cual se guardan los nombres y las contraseñas de los usuarios.

En Firebird 2.x el nombre de esa Base de Datos es SECURITY2.FDB y la encontrarás en la misma carpeta donde instalaste al Firebird.

¿Cómo se soluciona ese error?

Si tienes más de una instancia del Firebird instalada entonces cada instancia usa su propio puerto (o así debería ser si se instaló correctamente). Por lo tanto la solución es indicarle que abra el archivo SECURITY2.FDB que corresponde a la instancia que estemos usando en ese momento.

GSEC2

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

Como puedes ver en la Captura 2. se indico la IP de la computadora y el puerto 3050. Como ese es el puerto que le corresponde a la instancia del Firebird que nos interesa, funcionó perfectamente.

Después de la opción -database se escribió la ruta completa entre comillas porque hay un espacio en blanco en el medio, y en esos casos el Windows exige que se usen comillas.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

Anuncios

¿Qué datos guardar de una Factura?

16 comentarios

Este tema ya ha sido discutido en artículos anteriores pero siempre viene bien darle un breve repaso. Veo que aún hay mucha gente que tiene problemas conceptuales con el mismo.

El punto es muy sencillo: cualquier documento que pueda ser impreso y cuyos datos estaban correctos en el momento de la impresión debe poder ser vuelto a imprimir exactamente igual a la primera vez.

¿Por qué eso?

Porque en el momento de la impresión de un documento esos datos que se ven en él son los correctos (o al menos se supone que los son). Si más tarde por cualquier motivo se necesita reimprimir ese mismo documento entonces la reimpresión debe ser una copia exacta de lo que se imprimió la primera vez. Si eso no es así podrás tener problemas con la autoridad impositiva de tu país, porque a la gente del gobierno no le gusta que los documentos sean distintos.

Y tienen toda la razón del mundo, si a un cliente le diste una Factura por un total de 1.000 dólares y unos meses después al consultar esa Factura se ve que la venta fue de sólo 800 dólares hay un grave problema allí. Y en la mayoría de los países alguien se irá a la cárcel por eso o al menos pagará una fuerte multa, y todo eso podría haberse evitado si la Base de Datos hubiera estado cuidadosamente diseñada.

Entonces, lo que se imprime y sale de la Empresa no se debe normalizar.

En la gran mayoría de los casos, lo mejor y lo recomendable es que las tablas estén normalizadas. En este caso especial lo correcto es que no lo estén.

¿Por qué?

Porque si en la Factura el cliente tiene una dirección y un teléfono, después se muda, se actualizan su dirección y su teléfono en la tabla de CLIENTES, se reimprime la Factura y aparecerán en ella los nuevos datos, y eso está mal. Deberían aparecer los datos originales.

Eso hasta podría ser conversable con la gente del gobierno porque no hubo evasión impositiva ahí, pero ¿y si se cambió la cantidad de productos vendidos o los precios de venta?

Eso ya es otra cosa y un problema gravísimo. Porque eso sí puede provocar evasión impositiva, un delito muy grave en casi todos los países.

Entonces, en nuestra tabla de detalles de ventas tendríamos que guardar el Identificador del Producto vendido y también su código y también su nombre.

¿Y cómo evitamos que se modifiquen la cantidad vendida o el precio de venta o cualquier otro dato de detalle?

Con un trigger que se dispara cuando se quiere actualizar una fila, y envía una excepción.

IF UPDATING THEN
   EXCEPTION E_NO_SE_PUEDE_MODIFICAR_ESTA_FILA

¿Y cómo evitamos que se borre una fila?

Con un trigger que se dispara cuando se quiere borrar una fila y envía una excepción.

IF DELETING THEN
   EXCEPTION E_NO_SE_PUEDE_BORRAR_ESTA_FILA

¿Y si está todo mal y queremos borrar esa Factura?

Para este caso legítimo en nuestra tabla de cabecera tendremos una columna que nos indique que la Factura está anulada. Eso implica que la Factura jamás se borra de la tabla, simplemente se le pone una marca de que sus datos no deben ser utilizados en la mayoría de los informes.

Conclusión:

Los datos que se imprimen en documentos que salen de la Empresa deben ser siempre los mismos, no importa cuando ni cuantas veces se reimprima ese documento. Si eso no se hace así entonces alguna vez se podrán tener graves problemas con los clientes, con los proveedores o mucho peor, con el gobierno.

Para asegurar de que los datos sean siempre los mismos, las tablas donde se encuentran los datos que se imprimirán no deben estar normalizadas. En general, en la gran mayoría de los casos lo correcto es que las tablas sí estén normalizadas, pero en este caso particular (documentos que salen de la Empresa) lo correcto y lo recomendable es que no lo estén.

Para evitar que una fila se modifique podemos usar un trigger que impedirá las modificaciones. Para evitar que una fila sea borrada podemos usar un trigger que impedirá el borrado. Por supuesto que podremos usar un solo trigger para realizar ambas tareas.

Haciendo así nos aseguraremos de que siempre, sin importar cuanto tiempo haya pasado, nuestra Base de Datos mostrará información consistente.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

 

¿Cuándo se actualiza la estructura de una tabla?

4 comentarios

Si con un programa cambias la estructura de una tabla y con otro programa quieres usar esos cambios notarás que a veces no puedes hacerlo.

Veamos un ejemplo:

El usuario ejecuta su programa de Contabilidad y está trabajando con ese programa. Quiere introducir el nombre de un Proveedor y la columna le queda corta, digamos que solamente puede introducir 25 caracteres y él necesita introducir 31. Te llama y tú le dices: “ok, no hay problema, ya te actualizo la estructura de la tabla”.

Entonces vas, abres el EMS SQL Manager (o cual sea tu administrador gráfico), y cambias el ancho de la columna a 40, compilas la tabla, y está todo ok. Haces una prueba modificando esa columna en una fila cualquiera para que tenga 40 caracteres, le haces el COMMIT correspondiente y todo bien, funcionó perfecto. Desde luego, para terminar tu prueba borras los caracteres que le habías agregado a esa columna para probar, para que no queden registrados.

Ya has comprobado que aumentar el tamaño de la columna funcionó perfectamente entonces le llamas al usuario, y le dices: “ya está, ya podrás introducir hasta 40 caracteres en esa columna”.

El usuario feliz intenta nuevamente grabar los 31 caracteres que necesitaba grabar y … ¡¡¡NO FUNCIONA!!!

Te llama y te dice: “sigue sin funcionar, está igual que antes”

Entonces tú como eres muy educado a él no le dices una palabra pero dentro tuyo piensas: “¡¡¡la regranp…que lo recontraparió!!! ¡¡¡CÓMO QUE NO FUNCIONA!!! ¡¡¡Acabo de probar y funcionaba perfecto!!!”

Vuelves a probar y funciona bien. El usuario vuelve a probar y no le funciona.

¿Qué está pasando, cuál es el problema?

Que en tu programa los cambios sí funcionan, pero en el programa del usuario no. ¿Por qué?

Porque tú mantienes abierta a la Base de Datos en tu EMS SQL Manager (o cual sea tu administrador gráfico) y por lo tanto el usuario no se enterará de los cambios que hiciste hasta que no cierres la Base de Datos o salgas de ese programa.

Y en ocasiones, puede requerirse que el usuario también salga de su programa y vuelva a entrar.

Conclusión:

Que tú hagas un cambio a la estructura de una tabla no significa que al instante todos los usuarios se enteran de ese cambio, no es así. Para que se enteren debes salir del programa que usaste para realizar los cambios (el EMS SLQ Manager, el IBEXPERT, el FlameRobin, etc.) y en ocasiones el usuario también deberá salir del programa que él estaba usando. Solamente después de eso los cambios a la estructura de la tabla serán visibles.

Así que si haces cambios a una tabla y el usuario no ve esos cambios, no te desesperes. Simplemente sal de tu administrador gráfico y pídele al usuario que también salga del programa que estaba usando; cuando vuelva a entrar el asunto estará solucionado.

Artículo relacionado:

El índice del blog Firebird21

Como impedir que los usuarios modifiquen el valor de una columna

1 comentario

A veces, los valores que una vez se ingresaron en una columna deben ser siempre los mismos, son estáticos, no deben cambiarse.

En general los códigos tienen esta particularidad, deben ser fijos. Una vez asignados, ya no deberían ser modificados.

Sin embargo, podríamos olvidarnos de deshabilitar esa posibilidad en nuestro programa, el que ejecutan los usuarios y que escribimos en un lenguaje de programación: Visual FoxPro, Visual Basic, Delphi, C, C++, Java, etc.

Afortunadamente con Firebird es muy fácil evitar que cambien el valor de una columna, como podemos ver a continuación:

SET TERM ^ ;

CREATE TRIGGER CATEG_ACTIVO_BU FOR CATEG_ACTIVO
   ACTIVE BEFORE UPDATE
   POSITION 1
AS
BEGIN

   NEW.CAT_CODIGO = OLD.CAT_CODIGO;

END^

SET TERM ; ^

Al tener un trigger BEFORE UPDATE (en castellano: antes de actualizar) que le asigne a una columna el mismo valor que ya tenía esa columna nos aseguramos que jamás pueda cambiarse su valor. No importa cuantas veces lo intenten, no conseguirán cambiarlo.

Esta es una buena medida de seguridad, para evitar que por equivocación o por ignorancia, cambien lo que no debería ser cambiado.

Artículo relacionado:

El índice del blog Firebird21

Insertar, modificar o borrar filas en una Base de Datos externa

10 comentarios

En general, lo recomendable es que todas tus tablas estén en una sola Base de Datos ya que así puedes relacionar muy fácilmente a esas tablas entre sí. Sin embargo a veces no puedes evitar tener dos o más bases de datos. En ese caso: ¿cómo harías para insertar, modificar o borrar filas en una tabla que se encuentra en la otra Base de Datos?

El comando EXECUTE STATEMENT viene rápidamente en tu ayuda.

CREATE PROCEDURE INSERTAR_EN_BASEDATOS_EXTERNA_1
AS
   DECLARE VARIABLE lcComando VARCHAR(200);
   DECLARE VARIABLE lnIdenti  BIGINT;
   DECLARE VARIABLE lcNombre  VARCHAR(40);
BEGIN

   lnIdenti = 0;
   lcNombre = '''Esta es una prueba''';

   lcComando = 'INSERT INTO TARJETAS(TAR_IDENTI, TAR_NOMBRE) VALUES(' ||
               :lnIdenti || ',' || :lcNombre || ')';

   EXECUTE STATEMENT
      lcComando
   ON EXTERNAL
      'E:\BASESDATOS\CONTABILIDAD.FDB'
   AS
      USER 'SYSDBA' PASSWORD 'masterkey';
END;

Como puedes ver la variable lcNombre está rodeada por tres apóstrofos ¿por qué eso? porque si no se hace así ocurre un error ya que el contenido de esa variable debe estar rodeado de apóstrofos en el comando INSERT INTO. Cuando quieres que dentro de un string aparezca un apóstrofo debes escribir dos apóstrofos seguidos. Por ese motivo tuve que escribir tres apóstrofos.

Quizás también hayas notado que aunque la variable lnIdenti es numérica se la concatenó sin necesidad de convertirla previamente a tipo carácter, esa es una gran facilidad que nos da el Firebird.

En este ejemplo, los valores que insertamos en las columnas TAR_IDENTI y TAR_NOMBRE son constantes, sin embargo lo más común es que necesitemos insertar valores variables, como se ve en el siguiente ejemplo:

CREATE PROCEDURE INSERTAR_EN_BASEDATOS_EXTERNA_2(
   tnIdenti BIGINT,
   tcNombre VARCHAR(40))
AS
   DECLARE VARIABLE lcComando VARCHAR(200);
BEGIN

   lcComando = 'INSERT INTO TARJETAS(TAR_IDENTI, TAR_NOMBRE) VALUES(' ||
               :tnIdenti || ',''' || :tcNombre || ''')';

   EXECUTE STATEMENT
      lcComando
   ON EXTERNAL
      'E:\BASESDATOS\CONTABILIDAD.FDB'
   AS
      USER 'SYSDBA' PASSWORD 'masterkey';

END;

En este ejemplo los datos a insertar en la tabla externa fueron enviados como parámetros al stored procedure. Fíjate bien como el parámetro :tcNombre está rodeado por apóstrofos. Debes escribir esos apóstrofos para que funcione.

 Conclusión:

Para poder insertar, modificar o borrar filas en una tabla que se encuentra en otra Base de Datos debemos crear un string y luego ejecutarlo con el comando EXECUTE STATEMENT. Hay que tener en cuenta que las variables de tipo carácter deben estar rodeadas por apóstrofos.

Artículo relacionado:

https://firebird21.wordpress.com/2013/04/18/execute-statement/