Pregunta

Creo que lo mejor es pedirlo en forma de un ejemplo simple. La siguiente parte de SQL provoca un " DB-Library Error: 20049 Gravedad: 4 Mensaje: la conversión de datos generó un mensaje de desbordamiento " , pero ¿por qué?

declare @a numeric(18,6), @b numeric(18,6), @c numeric(18,6)
select @a = 1.000000, @b = 1.000000, @c = 1.000000
select @a/(@b/@c)
go 

¿Cómo es esto diferente a:

select 1.000000/(1.000000/1.000000)
go

que funciona bien?

¿Fue útil?

Solución

Me encontré con el mismo problema la última vez que intenté usar Sybase (hace muchos años). Partiendo de la mentalidad de SQL Server, no me di cuenta de que Sybase intentaría forzar a los decimales, lo que, matemáticamente, es lo que debería hacer. :)

De la Sybase manual :

  

Los errores de desbordamiento aritmético ocurren cuando   el nuevo tipo tiene muy pocos decimales   lugares para acomodar los resultados.

Y más abajo:

  

Durante conversiones implícitas a numéricas   o tipos decimales, pérdida de escala   genera un error de escala. Utilizar el   Arithabort numeric_truncation opción   para determinar qué tan grave es tal error   se considera. La configuración por defecto,   arithabort numeric_truncation en,   aborta la declaración que causa la   error pero sigue procesando otra   declaraciones en la transacción o   lote. Si pones arithabort   Numeric_truncation off, Adaptive   El servidor trunca los resultados de la consulta y   continúa el procesamiento.

Entonces, suponiendo que la pérdida de precisión es aceptable en su escenario , es probable que desee lo siguiente al comienzo de su transacción:

SET ARITHABORT NUMERIC_TRUNCATION OFF

Y luego al final de su transacción:

SET ARITHABORT NUMERIC_TRUNCATION ON

Esto es lo que me lo resolvió hace muchos años ...

Otros consejos

Esto es solo una especulación, pero ¿podría ser que el DBMS no vea el valor dinámico de sus variables sino solo los valores potenciales? Por lo tanto, un número de seis decimal dividido por un número de seis decimal podría resultar en un número de doce decimal; en la división literal, el DBMS sabe que no hay desbordamiento. Sin embargo, aún no estoy seguro de por qué le importaría al DBMS, ¿no debería devolver el resultado de dos divisiones de seis decimales con un número de 18 decimales?

Debido a que ha declarado las variables en el primer ejemplo, se espera que el resultado sea de la misma declaración (es decir, numérico (18,6)) pero no lo es.

Tengo que decir que el primero funcionó en SQL2005 (devolvió 1.000000 [el mismo tipo declarado]), mientras que el segundo regresó (1.000000000000000000000 [Una declaración totalmente diferente]).

No está directamente relacionado, pero podría ahorrarle a alguien algún tiempo con los errores de desbordamiento aritmético utilizando Sybase ASE (12.5.0.3).

Estaba configurando algunos valores predeterminados en una tabla temporal que intenté actualizar más adelante, y me topé con un error de desbordamiento aritmético.

declare @a numeric(6,3)

select 0.000 as thenumber into #test --indirect declare

select @a = ( select thenumber + 100 from #test )

update #test set thenumber = @a

select * from #test

Muestra el error:

Arithmetic overflow during implicit conversion of NUMERIC value '100.000' to a NUMERIC field .

Lo que en mi cabeza debería funcionar, pero no funciona como la columna 'thenumber' no se declaró (o se declaró indirectamente como decimal (4,3)). Por lo tanto, tendría que declarar indirectamente la columna de la tabla temporal con la escala y la precisión al formato que desee, como en mi caso fue 000.000.

select 000.000 as thenumber into #test --this solved it

Esperemos que le ahorre tiempo a alguien :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top