web-dev-qa-db-fra.com

Un moyen simple d'éviter une erreur de division par zéro en SQL

J'ai une requête SQL qui provoquait une 

Exception diviser par zéro

Je l'ai enveloppé dans une déclaration CASE pour empêcher que cela ne se produise. Y a-t-il un moyen plus simple de faire cela?

Voici mon code:

Percentage =  CASE WHEN AttTotal <> 0 THEN (ClubTotal/AttTotal) * 100 ELSE 0 END
12
Denys Wessels

Une meilleure façon de faire est d’utiliser NULLIF comme ceci:

Percentage =  100 * ClubTotal / NULLIF(AttTotal, 0)
39
Tom Chantler

J'utilise NULLIF un peu différemment, car dans certains cas, je dois renvoyer une valeur. Généralement, je dois renvoyer 0 lorsqu'il y a une erreur de division par zéro. Dans ce cas, j'emballe l'expression entière dans ISNULL. Donc ce serait:

Percentage =  ISNULL(100 * ClubTotal / NULLIF(AttTotal, 0), 0)

La partie interne est évaluée à NULL et ensuite ISNULL la remplace par 0.

7
PiotrWolkowski
Percentage =  IsNull(ClubTotal/NullIf(AttTotal, 0) * 100, 0)
5
i-one

À mon avis, la déclaration de CASE est exactement la voie à suivre. Plutôt que de calculer quelque chose, indiquez la valeur à renvoyer pour le cas où AttTotal vaut zéro. Vous pouvez même ajouter une autre branche de cas pour que 0 sur 0 soit 100%.

Juste une note de côté: je ne retournerais pas 0 quand AttTotal vaut zéro et ClubTotal est supérieur à zéro. NULL pourrait être plus approprié. Vous pouvez également créer des chaînes (par exemple, "10,50%") plutôt que des nombres (par exemple, 10,5%), contenant "Pas de total d'att." Dans le cas où AttTotal vaut zéro

PercentageString :=
  CASE
    WHEN AttTotal = 0 AND ClubTotal = 0 then '100%'
    WHEN AttTotal = 0 AND ClubTotal <> 0 THEN 'No att. total'
    ELSE to_char(ClubTotal / AttTotal * 100) || '%'
  END;
1
Thorsten Kettner

La solution que j’ai trouvée pour traiter le problème de la division par zéro est de créer une fonction à laquelle je peux faire appel pour faire face à la situation, car j’ai souvent à effectuer une sorte d’analyse de type ratio/pourcentage. Voici la fonction simple que j'ai écrite.

Create Function fnRatio(@Numerator decimal(10,2),@Demoninator decimal(10,2))

Returns decimal(10,2)

Begin

Return

Case 

      When @Demoninator = 0 then 0.00 



      When @Demoninator Is Null then Null



Else

      @Numerator/@Demoninator

End 

Fin

Cordialement

Jason

0
Jason