Éviter une erreur de division par zéro dans une colonne calculée


8

Comment éviter de diviser par zéro l'erreur dans le tableau ci-dessous?

CREATE TABLE [dbo].[TblDivision]
(
    [Numerator] int NOT NULL,
    [Denominator] int NOT NULL,
    [Result] AS (Numerator/ Denominator)
)
GO
Insert into (Numerator, Denominator) TblDivision values (3,0)
GO

1
S'il n'est pas valide pour que le dénominateur soit nul, vous pouvez ajouter une contrainte de vérification sur cette colonne. Cela ne répond pas à la question, car cela entraîne uniquement une erreur plus significative (plus proche de la source du problème) plutôt que d'éviter complètement une erreur.
David Spillett

Avez-vous l'intention d'utiliser la division entière ici ou non?
Martin Smith

Avez-vous envisagé de ne pas autoriser 0 à être une valeur dans cette colonne? Généralement, ce que j'ai vu est un sproc utilisé pour les applications clientes, plutôt que du SQL simple.

Réponses:


12

Ajoutez simplement un cas spécial pour la division par 0:

CREATE TABLE [dbo].[TblDivision]
  (
  [Numerator] int NOT NULL,
  [Denominator] int NOT NULL,
  [Result] AS case when Denominator=0 then 0 else (Numerator/ Denominator) end
  );

4
Ou peut-être retourner NULL plutôt que 0 si les NULL ne sont pas un problème pour le code lisant cette colonne, car le résultat de la division par zéro n'est pas vraiment 0 à moins que le numérateur soit 0.
David Spillett

3
Ouais, laissé comme exercice pour l'OP, pour être honnête. Éviter l'erreur a été répondu :)
Philᵀᴹ

10

Similaire à la solution de @ Phil:

CREATE TABLE dbo.TblDivision
(    Numerator int NOT NULL
,    Denominator int NOT NULL
,    Result AS Numerator / nullif(Denominator,0)
);

Si le dénominateur est 0, il est mappé sur null via nullif. Puisque tout ce qui est divisé par null est nul, le résultat devient nul dans ce cas.


Bien sûr, c'est la solution la plus propre. J'accepterais celui-ci.
Christiaan Westerbeek

-2
case 
 when Denominator=0 then 0 
 else Numerator/ Denominator 
end as [Result] 
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.