Error 10061

Deja un comentario

Es una muy buena práctica mirar todos los días el contenido del archivo FIREBIRD.LOG porque en ese archivo veremos todos los problemas que tuvo el Servidor del Firebird.

El archivo FIREBIRD.LOG encontrarás en la misma carpeta donde instalaste al Firebird, por ejemplo en:

C:\ARCHIVOS DE PROGRAMA\FIREBIRD\FIREBIRD_2_5\

Si ves una entrada similar a la siguiente:

POS003 (Client) Wed Jul 20 10:27:53 2016
INET/inet_error: connect errno = 10061
ese número de error 10061 significa que se rechazó la conexión.
¿Por qué se rechazó la conexión?
  • Porque el Servidor del Firebird no está ejecutándose en ese momento
  • Porque el número del puerto de conexión es incorrecto

Si por ejemplo, el Servidor del Firebird está usando el puerto 3051 y no especificaste el puerto 3051 en tu string de conexión, obtendrás ese mensaje de error.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

 

Stored procedures con cantidad de parámetros variables

2 comentarios

En ocasiones necesitamos escribir un stored procedure que recibirá varios parámetros de entrada pero cuando llamamos a ese stored procedure la cantidad de parámetros que le enviamos puede variar, no es siempre la misma cantidad y ni siquiera sabemos de antemano cuales y cuantos parámetros necesitaremos.

¿Podemos escribir un stored procedure que acepte una cantidad variable de parámetros, existe una forma de hacerlo?

Ejemplo: Necesitamos consultar a una tabla de VENDEDORES pero a veces el dato que conocemos es su Identificador, a veces es el Nombre, y a veces es la Fecha de Nacimiento.

SP01

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

Listado 1.

CREATE PROCEDURE SP_CONSULTAR_VENDEDORES (
   tnParam1 SMALLINT,
   tcParam2 VARCHAR(40),
   tdParam3 DATE)
RETURNS(
   ftnIdenti TYPE OF COLUMN VENDEDORES.VEN_IDENTI,
   ftcNombre TYPE OF COLUMN VENDEDORES.VEN_NOMBRE,
   ftdFecNac TYPE OF COLUMN VENDEDORES.VEN_FECNAC)
AS
   DECLARE VARIABLE lnValor1 SMALLINT;
   DECLARE VARIABLE lcValor2 VARCHAR(40);
   DECLARE VARIABLE ldValor3 DATE;
BEGIN

   FOR SELECT
      VEN_IDENTI,
      VEN_NOMBRE,
      VEN_FECNAC
   FROM
      VENDEDORES
   WHERE
      VEN_IDENTI = COALESCE(:tnParam1, VEN_IDENTI) AND
      VEN_NOMBRE = COALESCE(:tcParam2, VEN_NOMBRE) AND
      VEN_FECNAC = COALESCE(:tdParam3, VEN_FECNAC)
   INTO
      :lnValor1,
      :lcValor2,
      :ldValor3
   DO BEGIN
      ftnIdenti = lnValor1;
      ftcNombre = lcValor2;
      ftdFecNac = ldValor3;
      SUSPEND;
   END

END;

En este caso se trata de un stored procedure seleccionable pero exactamente la misma lógica usaríamos si se tratara de un stored procedure ejecutable. OBSERVACIÓN: en un stored procedure tan simple como este no es necesario usar variables locales, podríamos haber usado solamente los parámetros de salida, pero se muestra el caso general que puede ser más útil.

Entonces, podríamos escribir algo como:

Listado 2.

SELECT
   *
FROM
   SP_CONSULTAR_VENDEDORES(NULL, 'CLAUDIA', NULL)


Y obtendríamos lo siguiente:

SP02

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

Y si escribimos algo como:

Listado 3.

SELECT
   *
FROM
   SP_CONSULTAR_VENDEDORES(NULL, NULL, CAST('30/OCT/1994' AS DATE))

entonces obtendríamos lo siguiente:

SP03

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

Como ves, los parámetros desconocidos o innecesarios completamos con NULL, porque este stored procedure debe recibir sí o sí 3 parámetros de entrada.

Conclusión:

Si necesitamos varios stored procedures que son muy similares y la única diferencia entre ellos está en los parámetros de entrada entonces lo más conveniente es escribir un solo stored procedure y al llamarlo hacerlo con el parámetro o los parámetros adecuados en ese momento.

El truco está en usar la función COALESCE() para saber si un parámetro de entrada es NULL o tiene un valor distinto que NULL. Así sabremos si se le asignó un valor, o no.

Artículos relacionados:

La función COALESCE()

El índice del blog Firebird21

El foro del blog Firebird21

Firebird 2.5.6 ha sido liberado

Deja un comentario

La última versión de la serie 2.5 de Firebird ya se encuentra disponible para ser descargada y utilizada.

Descargar Firebird 2.5.6

Un archivo .PDF con las notas correspondientes a esa versión se puede descargar desde:

Firebird 2.5 Release Notes

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

 

Firebird 3: software de 32 bits y de 64 bits

3 comentarios

Si nuestro Servidor es Firebird 3, debemos recordar lo siguiente:

  1. Si la aplicación que deseamos ejecutar fue compilada en 32 bits (nuestra propia aplicación, IBExpert, FlameRobin, etc.) entonces se requiere el archivo FBCLIENT.DLL de 32 bits, aún cuando el Servidor del Firebird 3 sea de 64 bits. Si es nuestra aplicación la que fue compilada en 32 bits entonces lo aconsejable es que el archivo FBCLIENT.DLL de 32 bits se encuentre en la misma carpeta en la cual se encuentra nuestro .EXE, así evitamos confusiones con otros archivos FBCLIENT.DLL que pudieran encontrarse en la misma computadora.
  2. Un Servidor Firebird 3 de 64 bits puede aceptar conexiones de un FBCLIENT.DLL de 32 bits o de 64 bits, indistintamente. Un Servidor Firebird 3 de 32 bits solamente puede aceptar conexiones de un FBCLIENT.DLL de 32 bits.
  3. La ODS (On Disk Structure) de una Base de Datos creada con Firebird 3 es exactamente la misma, sea que esa Base de Datos haya sido creada con la versión de 32 bits o con la versión de 64 bits.
  4. No se debe permitir la conexión a una Base de Datos con el Servidor de 32 bits y con el Servidor de 64 bits al mismo tiempo. O con el uno, o con el otro, pero no con ambos a la vez porque eso corromperá a la Base de Datos.

Artículos relacionados:

¿Qué es la versión de ODS?

Firebird 3: usando bases de datos anteriores

El índice del blog Firebird21

El foro del blog Firebird21

 

 

 

Como decir NO diciendo SÍ

4 comentarios

A veces un cliente te pide que hagas un trabajo que tú no quieres hacer pero tampoco quieres quedar mal con tu cliente respondiéndole que no harás lo que te pide.

Cuando una persona pide algo siempre quiere escuchar un “Sí” por respuesta, nadie quiere escuchar un “No” por respuesta.

Entonces ¿cómo le decimos “NO” pero diciéndole “SÍ”?

El truco es:

  1. Decirle que por “a” o “b” motivo, no será fácil ni rápido hacer lo que te pide
  2. Decirle que le costará bastante dinero

Entonces, tu respuesta podría ser algo como: “Sí, puedo hacer eso, no hay problema, pero no será rápido porque tengo que cambiar primero la estructura de la Base de Datos, crear índices, verificar que las Foreign Keys sean las adecuadas y que no exista conflicto con ningún stored procedure, también tengo que revisar los triggers por las dudas. Creo que podría terminar en unos 15 días, y te costará 1.000 dólares, la mitad me das ahora y la mitad cuando termine tu pedido. ¿Quieres que empiece ahora mismo?”

Cuando le pidas 1.000 dólares (por un trabajo que tú sabes que como máximo vale 20 dólares) pueden ocurrir dos cosas:

  1. El cliente te dirá que lo pensó mejor y que realmente no necesitaba eso que te está pidiendo. Esto te ocurrirá en el 99,99% de los casos.
  2. Te dirá que empieces nomás, porque realmente necesita lo que te pide.

Como de lejos lo más probable es que suceda la primera alternativa, habrás conseguido tu objetivo: no hacer lo que te pide. Pero con el valor agregado de que le dijiste que sí lo querías hacer.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

 

 

DSN de archivo con EXCEL

Deja un comentario

En los ejemplos vistos hasta aquí, para enviar el contenido de las tablas o de las vistas de una Base de Datos del Firebird a Excel usábamos un DSN de usuario previamente definido. Funcionaba bien, pero nos obligaba a definir previamente ese DSN.

DSN01

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

Ahora veremos una alternativa que en muchos casos nos resultará mucho mejor: crear un DSN de archivo.

Creando un archivo .DSN

Los datos que el Excel necesita para conectarse a una Base de Datos del Firebird podemos colocarlos en un archivo de texto. Las características de ese archivo de texto son:

  1. El nombre puede ser cualquiera
  2. La extensión debe ser .DSN
  3. La primera línea debe ser [ODBC]
  4. En las siguientes líneas deben colocarse los parámetros de conexión

DSN02

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

Como podemos ver en la Captura 2., en nuestro archivo de texto llamado CONSULTA-EXCEL.DSN hemos especificado todos los parámetros que Excel necesitará saber para poder conectarse a nuestra Base de Datos del Firebird.

Usando el archivo .DSN en Excel

Estando en Excel, hacemos clic en Datos | De otras fuentes | Desde Microsoft Query

DSN03

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

Y en el cuadro de diálogo “Elegir origen de datos” hacemos clic sobre el botón “Examinar…”, como vemos en la Captura 4.

DSN04

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

DSN05

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

Y buscamos en nuestro disco duro el archivo .DSN que nos interesa.

Si el Excel no puede localizar al archivo GDS32.DLL o al archivo FBCLIENT.DLL, entonces verás la ventanita mostrada en la Captura 6.

DSN06

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

¿La solución?

Copiar el archivo FBCLIENT.DLL en la misma carpeta en donde guardamos a nuestro archivo .DSN, o guardar nuestro archivo .DSN en la carpeta donde se encuentra el archivo FBCLIENT.DLL

En Windows se aconseja que tengas al archivo FBCLIENT.DLL en la misma carpeta en donde tienes a tu archivo .EXE

Y por lo tanto, a tu archivo .DSN también lo guardarás en esa carpeta.

A partir de aquí, se continúa como habíamos visto en los artículos:

Planillas EXCEL dinámicas con Firebird (1)

Planillas EXCEL dinámicas con Firebird (2)

Ventaja de usar un DSN de archivo

La ventaja es que ese DSN de archivo (que es un simple archivo de texto) puedes crearlo con tu aplicación, y eso es muy útil cuando la cantidad de bases de datos es grande o es variable.

Si tu usuario siempre se conectará a la misma Base de Datos, entonces podrías crear un DSN de usuario y listo, asunto solucionado. Pero si puede conectarse a muchas bases de datos o si se irán creando nuevas bases de datos lo conveniente es crear un DSN de archivo desde tu aplicación. Este caso puede darse, por ejemplo, si tienes una aplicación contable y para cada cliente del estudio contable se crea una Base de Datos. Un estudio contable puede tener decenas o centenas de bases de datos.

Artículos relacionados:

Usando EXCEL para leer bases de datos de Firebird

Planillas EXCEL dinámicas con Firebird (1)

Planillas EXCEL dinámicas con Firebird (2)

Enviando una consulta a EXCEL

El índice del blog Firebird21

El foro del blog Firebird21

Enviando una consulta a EXCEL

2 comentarios

Hay muchas formas de enviar el resultado de una consulta a una planilla Excel, aquí veremos una de esas formas.

NOTA: el código fuente está basado en Visual FoxPro pero puede ser fácilmente adaptado a otros lenguajes de programación.

La ventaja de este método es que nos resultará muy fácil enviar la consulta que queremos, al libro Excel que queremos, a la hoja Excel que queremos, en el rango que queremos mostraremos la consulta, y esa consulta puede estar basada en cualquier tabla o en cualquier vista de nuestra Base de Datos del Firebird.

Primero, creamos la función que se encargará de realizar la tarea.

Listado 1.

FUNCTION ENVIAR_EXCEL_CON_DSN
LParameters tcDSN, tcUsuario, tcPassword, tcConsulta, tcRango
Local lcMensajeError, lcConsulta, loExcel, loLibro, loHoja, loTabla, lcConexion, lcBaseDatos
   
  lcMensajeError = ""
  
  tcRango = iif(VarType(tcRango) <> "C", "A1", tcRango)    && Si no se definió donde colocar la tabla, se la coloca en la celda A1
  
  *-- Tratamos de crear un objeto Excel
  if Empty(lcMensajeError)
    loExcel = CreateObject("Excel.Application")
    lcMensajeError = iif(VarType(loExcel) <> "O", "No se pudo crear el objeto EXCEL, verifica si está instaldo EXCEL", lcMensajeError)
  endif
  
  *-- Si todo OK, tratamos de crear un libro Excel
  if Empty(lcMensajeError)
    loLibro = loExcel.Workbooks.Add
    lcMensajeError = iif(VarType(loLibro) <> "O", "No se pudo crear el libro de EXCEL", lcMensajeError)
  endif
  
  *-- Si todo OK, tratamos de crear una hoja en el libro Excel
  if Empty(lcMensajeError)
    loHoja = loLibro.Worksheets(1)
    lcMensajeError = iif(VarType(loHoja) <> "O", "No se pudo crear la hoja en el libro EXCEL", lcMensajeError)
  endif
  
  *-- Si todo OK, creamos el string de conexión a la Base de Datos del Firebird, usando el DSN de esa Base de Datos
  if Empty(lcMensajeError)
    lcConexion = "ODBC;DSN=" + tcDSN + ";USER=" + tcUsuario + ";PASSWORD=" + tcPassword
  endif
  
  *-- Si todo OK, tratamos de conectarnos a la Base de Datos del Firebird
  if Empty(lcMensajeError)
    loTabla = loHoja.QueryTables.Add(lcConexion, loHoja.Range(tcRango), tcConsulta)
    lcMensajeError = iif(VarType(loTabla) <> "O", "No se pudo crear la tabla de consulta en la planilla Excel", lcMensajeError)
  endif
  
  *-- Si todo OK, insertamos la tabla en la planilal Excel
  if Empty(lcMensajeError)
    #DEFINE xlInsertEntireRows 2
    loTabla.RefreshStyle = xlInsertEntireRows
    loTabla.Refresh
  endif
  
  *-- Si todoOK, mostramos la planilla Excel
  if Empty(lcMensajeError)
    loExcel.Visible = .T.
  endif
  
  *-- Liberamos de la memoria los objetos que habíamos creado
  loTabla = NULL
  loHoja  = NULL
  loLibro = NULL
  loExcel = NULL
  
Return(lcMensajeError)
*
*

Y después llamamos a esa función, con los parámetros que deseemos usar.

Listado 2.

Local lcDSN, lcUsuario, lcPassword, lcConsulta, lcMensajeError, lcRango
  
  lcDSN = "AUTOMUNDO-FIREBIRD"
  
  lcUsuario = "SYSDBA"
  lcPassword = "masterkey"
  
   lcConsulta = "SELECT " ;
              + "   ASC_ANOEJE, " ;
              + "   ASC_CODSUC, " ;
              + "   ASC_FECHAX, " ;
              + "   ASC_NUMERO " ;
              + "FROM " ;
              + "   V_CONTA_ABM_ASIENTOS " ;
              + "WHERE " ;
              + "   ASC_NUMERO >= 100 AND " ;
              + "   ASC_NUMERO <= 120"
  
  lcRango = "B5"
  
  lcMensajeError = ENVIAR_EXCEL_CON_DSN(lcDSN, lcUsuario, lcPassword, lcConsulta, lcRango)
  
  *-- Si ocurrió algún error, mostramos un mensaje al usuario
  if !Empty(lcMensajeError)
    #DEFINE MSG_ICONO_ERROR 16
    #DEFINE MSG_BOTON_ACEPTAR 0
    =MessageBox(lcMensajeError, MSG_ICONO_ERROR + MSG_BOTON_ACEPTAR, "Hay un problema...")
  endif
  
Return
*
*

Y así obtendremos una planilla similar a la siguiente:

EXCEL01

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

Por lo tanto, nos resultará muy sencillo crear una planilla Excel con los datos que el usuario pueda necesitar. Inclusive podríamos tener en nuestra aplicación una opción que le muestre todas las vistas disponibles y que le permita crear consultas personalizadas, a su gusto y paladar. Ya depende de la creatividad de cada uno hacer algo así.

Artículos relacionados:

Usando EXCEL para leer bases de datos de Firebird

Planillas EXCEL dinámicas con Firebird (1)

Planillas EXCEL dinámicas con Firebird (2)

El índice del blog Firebird21

El foro del blog Firebird21

 

Older Entries

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

Únete a otros 357 seguidores