Här är fem alternativ för att hantera felmeddelande 8134 "Dela med noll fel påträffat" i SQL Server.
Felet
Först, här är ett exempel på kod som producerar felet vi pratar om:
SELECT 1 / 0;
Resultat:
Msg 8134, Level 16, State 1, Line 1 Divide by zero error encountered.
Vi får felet eftersom vi försöker dividera ett tal med noll. Matematiskt är detta ingen mening. Du kan inte dividera ett tal med noll och förvänta dig ett meningsfullt resultat.
För att hantera detta fel måste vi bestämma vad som ska returneras när vi försöker dividera med noll. Till exempel kanske vi vill att ett nollvärde ska returneras. Eller så kanske vi vill att noll ska returneras. Eller något annat värde.
Nedan finns några alternativ för att hantera detta fel.
Alternativ 1:NULLIF()
Uttryck
Ett snabbt och enkelt sätt att hantera detta fel är att använda NULLIF()
uttryck:
SELECT 1 / NULLIF( 0, 0 );
Resultat:
NULL
NULLIF()
returnerar NULL
om de två angivna uttrycken har samma värde. Den returnerar det första uttrycket om de två uttrycken är olika. Därför, om vi använder noll som det andra uttrycket, får vi ett nollvärde närhelst det första uttrycket är noll. Dela ett tal med NULL
resulterar i NULL
.
SQL Server returnerar faktiskt redan NULL
på ett dividera-med-noll-fel, men i de flesta fall ser vi inte detta på grund av vår ARITHABORT
och ANSI_WARNINGS
inställningar (mer om detta senare).
Alternativ 2:Lägg till ISNULL()
Funktion
I vissa fall kanske du föredrar att returnera ett annat värde än NULL
.
I sådana fall kan du skicka det föregående exemplet till ISNULL()
funktion:
SELECT ISNULL(1 / NULLIF( 0, 0 ), 0);
Resultat:
0
Här specificerade jag att noll ska returneras när resultatet är NULL
.
Var dock försiktig. I vissa fall kan det vara olämpligt att returnera noll. Om du till exempel har att göra med lagerförnödenheter kan det innebära att noll anger att det inte finns några produkter, vilket kanske inte är fallet.
Alternativ 3:Använd en CASE
Uttalande
Ett annat sätt att göra det är att använda en CASE
uttalande:
DECLARE @n1 INT = 20;
DECLARE @n2 INT = 0;
SELECT CASE
WHEN @n2 = 0
THEN NULL
ELSE @n1 / @n2
END
Resultat:
NULL
Alternativ 4:SET ARITHABORT
Uttalande
SET ARITHABORT
satsen avslutar en fråga när ett spill eller dividera-med-noll-fel inträffar under exekveringen av frågan. Vi kan använda det tillsammans med SET ANSI WARNINGS
för att returnera NULL
närhelst dela-med-noll-felet kan inträffa:
SET ARITHABORT OFF;
SET ANSI_WARNINGS OFF;
SELECT 20 / 0;
Resultat:
NULL
Microsoft rekommenderar att du alltid ställer in ARITHABORT
till ON
i dina inloggningssessioner, och att ställa in den till OFF
kan negativt påverka frågeoptimering, vilket leder till prestandaproblem.
Vissa klienter (som SQL Server Management Studio) ställer in ARITHABORT
till ON
som standard. Det är därför du förmodligen inte ser NULL
värde som returneras när du dividerar med noll. Du kan använda SET ARITHIGNORE
för att ändra detta beteende om du föredrar det.
Alternativ 5:SET ARITHIGNORE
Uttalande
SET ARITHIGNORE
satsen styr om felmeddelanden returneras från spill eller dividera med noll fel under en fråga:
SET ARITHABORT OFF;
SET ANSI_WARNINGS OFF;
SET ARITHIGNORE ON;
SELECT 1 / 0 AS Result_1;
SET ARITHIGNORE OFF;
SELECT 1 / 0 AS Result_2;
Resultat:
Commands completed successfully. Commands completed successfully. Commands completed successfully. +------------+ | Result_1 | |------------| | NULL | +------------+ (1 row affected) Commands completed successfully. +------------+ | Result_2 | |------------| | NULL | +------------+ Division by zero occurred.
Här ställer jag in ARITHABORT
och ANSI_WARNINGS
till OFF
så att satsen inte avbröts på grund av felet, och NULL
returneras när det finns ett dividera-med-noll-fel.
Observera att SET ARITHIGNORE
inställningen styr bara om ett felmeddelande returneras. SQL Server returnerar en NULL
i en beräkning som involverar ett spill eller dividera med noll-fel, oavsett denna inställning.
I exemplet ovan kan vi se att när ARITHIGNORE
är ON
, returneras inte divisionen med nollfel. När den är OFF
, returneras felmeddelandet om divisionen med noll.