Pergunta

Eu acho que esta é a melhor pedida na forma de um exemplo simples. O seguinte pedaço de SQL causa um "Erro DB-Library: 20049 Gravidade: 4 Mensagem: Data-conversão resultou em overflow" mensagem, mas como?

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 

Como isso é diferente de:

select 1.000000/(1.000000/1.000000)
go

que funciona bem?

Foi útil?

Solução

Eu corri para o mesmo problema da última vez que eu tentei usar Sybase (há muitos anos). Vindo de uma mentalidade SQL Server, eu não sabia que Sybase iria tentar coagir os decimais - o que, matematicamente, é o que deve fazer. :)

A partir da Sybase Manual :

erros de estouro aritmético ocorre quando o novo tipo tem muito poucos decimal lugares para acomodar os resultados.

E mais abaixo:

Durante conversões implícitas para numérico ou tipos decimais, perda de escala gera um erro de escala. Use o opção numeric_truncation ARITHABORT para determinar o quão sério erro tal é considerado. A configuração padrão, ARITHABORT numeric_truncation on, aborta a afirmação de que faz com que o erro, mas continua a processar outra declarações relativos à operação ou batch. Se você definir ARITHABORT off numeric_truncation, Adaptive trunca servidor os resultados da consulta e continua o processamento.

Assim, assumindo que a perda de precisão é aceitável em seu cenário , você provavelmente quer o seguinte no início da sua transação:

SET ARITHABORT NUMERIC_TRUNCATION OFF

E, em seguida, no final da sua transação:

SET ARITHABORT NUMERIC_TRUNCATION ON

Isto é o que resolveu para mim muitos anos atrás ...

Outras dicas

Este é apenas especulação, mas pode ser que o DBMS não olha para o valor dinâmico de suas variáveis, mas apenas os valores potenciais? Deste modo, um valor numérico de seis decimal dividida por um valor numérico de seis decimal poderia resultar em uma numérico doze decimal; na divisão literal, o DBMS sabe que não há excesso. Ainda não tenho certeza por que os DBMS se importaria, embora -? Shouldn't-lo retornar o resultado de duas divisões de seis decimais como até um numérico de 18 decimal

Porque você declarou as variáveis ??no primeiro exemplo é esperado que o resultado seja da mesma declaração (ou seja numérico (18,6)), mas não é.

Eu tenho que dizer que o primeiro trabalhou em SQL2005 embora (retornou 1.000000 [O mesmo tipo declarado]), enquanto o segundo voltou (1,00000000000000000000000 [A declaração totalmente diferente]).

Não diretamente relacionados, mas poderia salvar alguém algum tempo com os erros de estouro aritmético que usam o Sybase ASE (12.5.0.3).

Eu estava assentado alguns valores padrão em uma tabela temporária que eu pretendia atualizar mais tarde, e tropeçou em um erro de estouro 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

Mostra o erro:

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

O que na minha cabeça deve funcionar, mas não como o 'thenumber' coluna não foi declarado (ou indiretamente declarado como decimal (4,3)). Então você teria que declarar indiretamente a coluna tabela temporária com escala e precisão para o formato desejado, como no meu caso era 000.000.

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

Esperamos que salva alguém de algum tempo:)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top