Evitare una divisione per zero errori in una colonna calcolata


8

Come evitare la divisione per errore zero nella tabella seguente?

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
Se non è valido che Denominator sia zero, è possibile aggiungere un vincolo di controllo su quella colonna. Ciò non risponde alla domanda, poiché si traduce solo in un errore più significativo (più vicino alla fonte del problema) piuttosto che evitare completamente un errore.
David Spillett,

Intendi utilizzare la divisione intera qui o no?
Martin Smith,

Hai considerato di non consentire a 0 di essere un valore in quella colonna? In genere quello che ho visto è uno sproc utilizzato per le applicazioni client, piuttosto che un semplice SQL.

Risposte:


12

Aggiungi un caso speciale per la divisione per 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
O forse restituisce NULL anziché 0 se i NULL non sono un problema per la lettura del codice di quella colonna, poiché il risultato di divisione per zero non è in realtà 0 a meno che il numeratore sia 0.
David Spillett

3
Sì, lasciato come esercizio per l'OP, a dire il vero. È stato risolto l'errore di evitare l'errore :)
Phil,

10

Simile alla soluzione di @ Phil:

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

Se Denominator è 0, viene mappato su null tramite nullif. Poiché tutto ciò che è diviso per null è nullo, in questo caso il risultato diventa nullo.


Naturalmente questa è la soluzione più pulita. Accetterei questo.
Christiaan Westerbeek,

-2
case 
 when Denominator=0 then 0 
 else Numerator/ Denominator 
end as [Result] 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.