Error de arithmetic overflow, division by zero, or string truncation, en un SELECT

3 comentarios

En ocasiones el contenido de una tabla puede dañarse. Por ejemplo, porque primero grabaste algunas filas con un character set y luego cambiaste el character set de la tabla, por otro que es incompatible.

En tales casos al hacerle un SELECT a esa tabla, podrías ver un mensaje de error como el siguiente:

"Arithmetic overflow or division by zero has occurred.
arithmetic exception numeric overflow or string truncation
cannot transliterate character between character sets"

 

¿Por qué podría ocurrir algo así?

Porque el Firebird no verifica que el nuevo character set sea compatible con el anterior y que todas las filas de la tabla puedan ser traducidas (transliteradas). Eso, porque la tabla puede ser muy grande, tener millones y millones de filas, y hacer esa comprobación podría demorar mucho tiempo. Entonces, es tu responsabilidad asegurarte de que lo que estás haciendo está bien, pero … a veces podrías equivocarte.

¿Qué hacer en este caso?

Una posibilidad es tratar de recuperar todas las filas posibles, aquellas filas que aún pueden ser leídas. Esto puede ser algo tedioso pero … hay que hacerlo.

Podríamos crear una tabla que tenga exactamente la misma estructura que la tabla original, pero vacía, sin datos. Sus datos los iremos insertando por partes.

Ejemplo:

El mensaje de error te aparece luego de mostrarte 782 filas al ejecutar el Listado 1.

Listado 1.

SELECT
   ALU_NOMBRE
FROM
   ALUMNOS

Entonces para ir insertando en nuestra tabla auxiliar por partes podríamos escribir algo como:.

Listado 2.

INSERT INTO ALUMNOS2
   (ALU_NOMBRE)
SELECT
   ALU_NOMBRE
FROM
   ALUMNOS
ROWS
   1 TO 782

Lo que hicimos fue crear una tabla llamada ALUMNOS2 que tiene exactamente la misma estructura que la tabla ALUMNOS y luego le insertamos todas las filas que sabemos que están bien.

Listado 3.

INSERT INTO ALUMNOS2
   (ALU_NOMBRE)
SELECT
   ALU_NOMBRE
FROM
   ALUMNOS
ROWS
   784 TO 99999999

Como sabemos que la fila 783 tiene un error entonces en el Listado 3. salteamos hasta esa fila y nuestro INSERT empezará en la fila 784. Si el SELECT del Listado 3. también nos muestra un mensaje de error entonces vamos cambiando la cantidad del SKIP a 785, 786, 787, etc., hasta que podamos realizar el INSERT exitosamente.

De esta manera, aunque no recuperaremos todas las filas de la tabla ALUMNOS, sí podremos recuperar todas las filas que no tenían problemas.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

 

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

 

Error SQLSTATE = HY000

Deja un comentario

Si cuando quieres conectarte a una Base de Datos el Firebird te muestra el error SQLSTATE = HY000 eso significa dos cosas:

  1. Que la conexión no se realizó
  2. Que la Base de Datos a la cual quisiste conectarte no la reconoce como una Base de Datos válida

El punto 2. por ejemplo puede ocurrir si quieres conectarte a un backup creado por el programa GBAK. El backup creado por el programa GBAK no puede ser usado directamente por el Firebird, debe ser restaurado usando también para la restauración al programa GBAK.

El error HY000 ocurre cuando el Firebird encontró el archivo pero no encontró una página de cabecera en él.

Artículos relacionados:

Entendiendo las páginas de la Base de Datos

El índice del blog Firebird21

El foro del blog Firebird21

 

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

Error: Too many Contexts of Relation/Procedure/Views. Maximum allowed is 255

1 comentario

Cuando escribes un stored procedure, un execute block, o una view hay un límite a la cantidad de contextos que puedes tener.

¿Qué es un contexto?

Es cualquier comando del Firebird que hace referencia a una tabla (o más de una).

Ese límite es por declaración, no por stored procedure, execute block o view. No hay que confundir.

Las declaraciones posibles son:

  • INSERT
  • UPDATE
  • DELETE
  • SELECT

Ninguna de esas declaraciones puede tener más de 255 contextos. Ese es el límite máximo.

Pero además, cada GROUP BY y cada UNION suma 1 contexto más.

Ejemplos:

  • Un SELECT a una tabla tiene un contexto
  • Un SELECT con un JOIN tiene dos contextos
  • Un SELECT con dos JOIN tiene tres contextos
  • Un SELECT con una subconsulta tiene dos contextos
  • Un SELECT con dos subconsultas tiene tres contextos
  • Un SELECT con una subconsulta y con un JOIN tiene tres contextos
  • Un SELECT autoreferenciado (ambas tablas del JOIN son la misma) tiene dos contextos
  • Un SELECT con un GROUP BY tiene dos contextos
  • Un INSERT que referencia a una view, tiene un contexto por cada tabla que es referenciada en la view
  • Un UPDATE que referencia a una view, tiene un contexto por cada tabla que es referenciada en la view

Cada INSERT, cada UPDATE y cada DELETE suma 2, por las seudo-variables NEW y OLD de los triggers. En los demás casos se suma 1.

La cantidad máxima de contextos que puedes tener (hasta la versión Firebird 3.0) es de 255, si superas esa cantidad entonces verás el mensaje de error que da título a este artículo.

Listado 1.


SELECT <mis_columnas_1> FROM MiTabla1;

UNION

SELECT <mis_columnas_2> FROM MiTabla2;

En el Listado 1. hay 3 contextos.

Listado 2.


INSERT INTO MiTabla <mis_columnas> VALUES <lista_valores>;

INSERT INTO MiTabla <mis_columnas> VALUES <otros_valores>;

En el Listado 2. el primer INSERT tiene 2 contextos y el segundo INSERT también tiene 2 contextos. Esos contextos no se suman, cada uno de ellos es independiente, porque lo que vale es la cantidad de contextos que cada declaración tiene.

Solución:

Si el Firebird te muestra este mensaje de error entonces tienes que disminuir la cantidad de contextos. Eso puedes hacerlo de varias maneras, por ejemplo usando una tabla CTE en lugar de varias subconsultas, o cambiando la condición de filtro del WHERE, o disminuyendo la cantidad de JOIN, etc.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

ERROR: Connection rejected by remote interface

5 comentarios

Si ves este mensaje (la conexión fue rechazada por la interface remota) la consecuencia es que el usuario no puede conectarse a la Base de Datos.

Un posible motivo es que está usando un cliente de InterBase en lugar de usar un cliente de Firebird.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

Error 802 en una consulta

1 comentario

En el foro preguntaron:

¿Por qué esta consulta:

Listado 1.

SELECT
   192.76110000000000 / 2.2200
FROM
   RDB$DATABASE

muestra el error: -802 Arithmetic overflow or division by zero has occurred.?

El problema, tal y como se explicó en el artículo Usando NUMERIC y DECIMAL es debido a la forma en que el Firebird define a los números escalados (también llamados de coma fija o de punto fijo; son sinónimos).

En Firebird los números escalados tienen el formato:

p.s

donde p indica la precisión y s indica la escala (s=scale, en inglés).

La precisión máxima en Firebird, hasta la versión 2.5.4 es de 18. La escala siempre debe ser menor o igual a la precisión, nunca puede ser mayor.

¿Cuál es la precisión del resultado cuándo se hace una división?

Siempre es 18.

¿Cuál es la escala del resultado cuándo se hace una división?

Siempre es la suma de la escala del numerador más la escala del denominador.

¿Cuál fue el problema en la división que dio origen a este artículo?

Que el numerador (192.76110000000000) tiene una escala de 14 y el denominador (2.2200) tiene una escala de 4. El resultado de la división por lo tanto tendrá una escala de 18 (es decir, 14 + 4). Ya está en el límite máximo permitido.

La división anterior sí funcionará si la parte entera del numerador es pequeña, por ejemplo:

Listado 2.

SELECT
   19.76110000000000 / 2.2200
FROM
   RDB$DATABASE

La parte entera del numerador es 19 y allí sí funciona.

¿Por qué funciona cuándo el numerador es pequeño?

Si la precisión es 18 entonces el número se guarda como un BIGINT. Los números de tipo BIGINT pueden encontrarse entre -2 * 10 ^ 63 y 2 * 10 ^ 63 – 1. O sea, entre -9.223.372.036.854.775.808 y +9.223.372.036.854.775.807

Si la escala es 18 entonces el Firebird divide a ese número por 1.000.000.000.000.000.000 o sea un 1 seguido por 18 ceros.

Al dividir 9.223.372.036.854.775.807 por 1.000.000.000.000.000.000 obtenemos: 9,223372036854775807

Por lo tanto, si la precisión es 18 y la escala es 18 (como en el Listado 1.) el resultado de la división debe ser 9,22 ó menor para no obtener un error de overflow.

Pero en el Listado 1. el resultado de la división es 86,829321…., ese número es mayor que 9,22 y entonces lo que se obtiene es un … error de overflow.

¿Y si necesitamos hacer sí o sí la división del Listado 1., cómo lo solucionamos?

Tenemos varias alternativas:

Listado 3.

SELECT
   192.7611 / 2.2200
FROM
   RDB$DATABASE

Le quitamos los ceros al numerador y funciona sin problemas porque ahora la escala es de 8.

Listado 4.

SELECT
   192.76110000000000 / 2.22
FROM
   RDB$DATABASE

Le quitamos los ceros al denominador y funciona sin problemas porque ahora la escala es de 16.

Listado 5.

SELECT
   CAST(192.76110000000000 AS NUMERIC(18, 13)) / 2.2200
FROM
   RDB$DATABASE

Empleamos la función CAST() para disminuir la escala del numerador y funcionó sin problemas.

Listado 6.

SELECT
   CAST(192.761100000000000 AS FLOAT) / 2.2200
FROM
   RDB$DATABASE

Empleamos la función CAST() para cambiar el tipo de datos del numerador a FLOAT y funcionó sin problemas.

Conclusión:

Tal y como se dijo en el artículo antes citado: “La precisión del resultado siempre es 18. La escala del resultado es la suma de las escalas del dividendo y del divisor. Esto implica que la escala del cociente siempre será mayor que las del dividendo y del divisor. Debes tener cuidado con esto si los números que empleas tienen muchos decimales o podrías sobrepasar la escala máxima que es 18 o necesitar una precisión mayor que 18 y en ambos casos eso te ocasionaría un error de overflow.”

Lo importante a recordar aquí por lo tanto es que si divides números que tienen muchos decimales puedes sobrepasar la escala máxima de 18 o necesitar una precisión mayor que 18 y en ambos casos tendrás un error de overflow.

Hay varios métodos para realizar la división de todos modos, algunos de los cuales vimos en los últimos listados de arriba (hay varios más, pero ya tienes la idea).

Artículos relacionados:

Usando NUMERIC y DECIMAL

El índice del blog Firebird21

El foro del blog Firebird21

Error 10060. No se puede conectar al Servidor

8 comentarios

Si en el archivo FIREBIRD.LOG, que se encuentra en la misma carpeta donde instalaste el Firebird, encuentras el error 10060 eso significa que no se pudo realizar la conexión con el Servidor porque ya transcurrió demasiado tiempo desde que se intentó la conexión y por eso fue rechazada.

Ocurre generalmente cuando el firewall (cortafuegos) bloquea la conexión al puerto 3050 (o al puerto que estés utilizando para conectarte con el Servidor).

Posibles soluciones:

  1. Configurar al firewall (cortafuegos) para que permita la conexión al puerto 3050 (o al que sea que esté usando el Servidor)
  2. Si en el string de conexión se estaba usando el nombre de la computadora donde se encuentra el Servidor, cambiarlo por el IP de la computadora donde se encuentra el Servidor. En muchos casos así se soluciona.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

Error: database file appears corrupt

8 comentarios

Como seguramente sabes, debes revisar constantemente el archivo FIREBIRD.LOG que encontrarás en la carpeta donde instalaste al Firebird para descubrir cualquier error que haya ocurrido.

¿Qué significa el error: “database file appears corrupt“?

Que el archivo de la Base de Datos (el cual usualmente tiene la extensión .FDB) está dañado.

¿Por qué se dañó la Base de Datos?

La causa más común es porque hubo un corte de la energía eléctrica en la computadora donde se encuentra el Servidor mientras se estaba realizando una operación de INSERT, UPDATE, o DELETE.

A veces también podría ocurrir si hay una súbita alta tensión. O si algún descerebrado apagó el Servidor mientras la Base de Datos estaba siendo usada.

Entonces, el problema fue causado por dos motivos:

  1. Se estaba realizando una operación de INSERT, UPDATE, DELETE
  2. En ese instante se detuvo el Servidor del Firebird

Otra causa, tal como señaló Yván Acosta en la sección de comentarios, es que usando el Explorador de Windows o algún programa similar, se haya copiado la Base de Datos. Hay varios métodos seguros para realizar backups de las bases de datos, y alguno de esos métodos seguros hay que usar.

¿Cuál es la solución?

Usar el programa FirstAID (primera ayuda) de IBSurgeon, que encontrarás en www.ib-aid.com

¿Cómo evitar que el problema vuelva a ocurrir?

  1. Primero y elemental, colocarle una UPS (uninterruptible power supply) de buena capacidad a la computadora donde se encuentra el Servidor
  2. Verificar, al menos una vez a la semana que la UPS esté funcionando correctamente. Para ello, cuando nadie esté conectado a la Base de Datos, desenchufar la UPS del tomacorriente y anotar el tiempo que mantiene a la computadora encendida. Las UPS van disminuyendo el tiempo en que sus baterías proveen de carga eléctrica. Jamás hay que creer que una UPS que se instaló hace un año sigue funcionando como cuando era nueva. En la gran mayoría de los casos, eso es falso.
  3. Evitar que la computadora donde se encuentra el Servidor sea apagada.
  4. Evitar que el Servidor sea detenido, manualmente o por algún otro programa.

Con relación al punto 3. tengo una anécdota. En una empresa grande, que tiene decenas de computadoras, súbitamente todo el mundo se desconectó de la Base de Datos, había energía eléctrica, las luces estaban encendidas, las computadoras también, pero no había conexión a la Base de Datos, caos total. ¿Qué había ocurrido? Que la señora de la limpieza, con su escoba había desenchufado al Servidor, y siguió limpiando como si nada, no le importó lo más mínimo porque ni siquiera sabía la importancia de que ese cable estuviera enchufado. Al salir, cerró la puerta de la habitación y como se encuentra alejada de la Administración nadie se percató que unos minutos después la UPS empezó a chillar como loca. Se aprendió la lección, ahora el Servidor está en una habitación aparte y la puerta siempre se mantiene cerrada con llave, por las dudas. Y duplicados de esa llave solamente tienen las personas adecuadas, ninguna “señora de la limpieza” puede entrar.

Con relación al punto 4. hay que tener cuidado con los antivirus u otros programas similares porque podrían detener al Servidor. Es por ese motivo que fuertemente se aconseja que en la computadora donde se encuentra el Servidor del Firebird no se esté ejecutando ningún otro programa, ninguno, ni siquiera un antivirus.

Conclusión:

Una Base de Datos puede corromperse si el Servidor deja de funcionar mientras estaba realizando una operación de INSERT, UPDATE, o DELETE.

El problema puede solucionarse con el programa FirstAID de IBSurgeon, pero lo más conveniente es evitar que el problema ocurra. Para ello, jamás debe detenerse el Servidor si alguien está conectado a la Base de Datos.

Artículos relacionados:

FirstAID de IBSurgeon

Reparación de una Base de Datos corrupta

Manteniendo la Base de Datos en buen estado

Los métodos para hacer backup

El índice del blog Firebird21

El foro del blog Firebird21

Error con Global Temporary Table

Deja un comentario

Las GTT (Global Temporary Table) son muy útiles porque nos permiten tener tablas temporarias, tablas que solamente existirán mientras dure la transacción o la conexión.

Pero cuando las tablas GTT son grandes y necesitan ser ordenadas fuera del sort buffer pueden ocurrir problemas. Si usamos un disco RAM para los archivos temporales (los creados cuando en un SELECT tenemos la cláusula ORDER BY y ningún índice disponible) podríamos obtener este mensaje de error:

Unsuccessful execution caused by a system error that precludes successful execution of subsequent statements.
I/O error during “CreateFile (create)” operation for file “”.
Error while trying to create file.
The system can not find the path specified.

¿Cuál es el problema?

Que la carpeta donde se guardan los archivos temporales se encuentra en un disco RAM.

¿La solución?

Indicarle al Firebird que no use un disco RAM para los archivos temporales.

¿Qué versiones de Firebird tienen este problema?

Se lo ha detectado en Firebird 2.5.4 de 64 bits usando Windows 8.1

Podría ocurrir también en otras versiones.

Artículos relacionados:

Creando y usando tablas temporales
Usando un disco RAM para aumentar la velocidad
Los archivos temporales del Firebird
Acelerando los SORT
Configurando al Firebird
El índice del blog Firebird21
El foro del blog Firebird21

Older Entries