Question

Je pense que le mieux est de poser cette question sous la forme d'un exemple simple. Le bloc SQL suivant provoque une " erreur DB-Library: 20049 Gravité: 4 Message: la conversion de données a entraîné un débordement du message "/ <; em>", mais comment se fait-il?

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 

En quoi est-ce différent de:

select 1.000000/(1.000000/1.000000)
go

qui fonctionne bien?

Était-ce utile?

La solution

J'ai rencontré le même problème la dernière fois que j'ai essayé d'utiliser Sybase (il y a de nombreuses années). En raison de l'état d'esprit de SQL Server, je n'avais pas compris que Sybase tenterait de contraindre les décimales - ce qui, mathématiquement, est ce qu'il devrait faire. :)

Extrait du Manuel Sybase :

  

Des erreurs de débordement arithmétique se produisent lorsque   le nouveau type a trop peu de décimales   endroits pour accueillir les résultats.

Et plus bas:

  

Au cours des conversions implicites en numériques   ou types décimaux, perte d'échelle   génère une erreur d'échelle. Utilisez le   Option arithabort numeric_truncation   pour déterminer la gravité d'une telle erreur   est considéré. Le réglage par défaut,   arithabort numeric_truncation on,   avorte la déclaration qui provoque la   erreur, mais continue à traiter d'autres   déclarations dans la transaction ou   lot. Si vous définissez arithabort   numeric_truncation off, adaptatif   Le serveur tronque les résultats de la requête et   poursuit le traitement.

Donc en supposant que la perte de précision est acceptable dans votre scénario , vous souhaitez probablement ce qui suit au début de votre transaction:

SET ARITHABORT NUMERIC_TRUNCATION OFF

Et ensuite à la fin de votre transaction:

SET ARITHABORT NUMERIC_TRUNCATION ON

C'est ce qui a résolu le problème pour moi il y a tant d'années ...

Autres conseils

Ceci n'est que spéculation, mais est-il possible que le SGBD ne considère pas la valeur dynamique de vos variables mais uniquement les valeurs potentielles? Ainsi, un nombre à six décimales divisé par un nombre à six décimales pourrait donner un nombre à douze décimales; dans la division littérale, le SGBD sait qu'il n'y a pas de dépassement de capacité. Vous ne savez toujours pas pourquoi le SGBD s’intéresserait, mais ne devrait-il pas renvoyer le résultat de deux divisions en six décimales avec un maximum de 18 décimales?

Comme vous avez déclaré les variables dans le premier exemple, le résultat devrait correspondre à la même déclaration (c'est-à-dire numérique (18,6)), mais ce n'est pas le cas.

Je dois dire que le premier fonctionnait bien dans SQL2005 (renvoyé 1.000000 [Le même type déclaré]), tandis que le second renvoyait (1.00000000000000000000000 [Une déclaration totalement différente]).

Pas directement lié, mais pourrait éventuellement faire gagner du temps aux erreurs de débordement arithmétique avec Sybase ASE (12.5.0.3).

Je définissais quelques valeurs par défaut dans une table temporaire que je souhaitais mettre à jour ultérieurement, et je suis tombé sur une erreur de débordement arithmétique.

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

Affiche l'erreur:

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

Ce qui dans ma tête devrait fonctionner, mais pas comme la colonne "thenumber" n'a pas été déclarée (ou indirectement comme décimale (4,3)). Vous devez donc déclarer indirectement la colonne de la table temporaire avec une échelle et une précision conformes au format souhaité, comme dans mon cas, 000 000.

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

Espérons que cela fera gagner un peu de temps à quelqu'un:)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top