Zde je pět možností, jak se vypořádat s chybovou zprávou 8134 „Nedošlo k chybě dělení nulou“ na serveru SQL.
Chyba
Nejprve je zde příklad kódu, který způsobí chybu, o které mluvíme:
SELECT 1 / 0;
Výsledek:
Msg 8134, Level 16, State 1, Line 1 Divide by zero error encountered.
Dostaneme chybu, protože se snažíme vydělit číslo nulou. Matematicky to nedává žádný smysl. Nemůžete dělit číslo nulou a očekávat smysluplný výsledek.
Abychom se s touto chybou vypořádali, musíme se rozhodnout, co by se mělo vrátit, když se pokusíme dělit nulou. Můžeme například chtít, aby byla vrácena hodnota null. Nebo můžeme chtít, aby se vrátila nula. Nebo nějakou jinou hodnotu.
Níže jsou uvedeny některé možnosti řešení této chyby.
Možnost 1:NULLIF()
Výraz
Rychlý a snadný způsob, jak se s touto chybou vypořádat, je použít NULLIF()
výraz:
SELECT 1 / NULLIF( 0, 0 );
Výsledek:
NULL
NULLIF()
vrátí NULL
pokud dva zadané výrazy mají stejnou hodnotu. Vrátí první výraz, pokud se dva výrazy liší. Pokud tedy jako druhý výraz použijeme nulu, získáme hodnotu null vždy, když je první výraz nula. Dělení čísla NULL
výsledkem je NULL
.
Ve skutečnosti SQL Server již vrací NULL
na chybě dělení nulou, ale ve většině případů to nevidíme kvůli našemu ARITHABORT
a ANSI_WARNINGS
nastavení (více o tom později).
Možnost 2:Přidejte ISNULL()
Funkce
V některých případech můžete dát přednost vrácení jiné hodnoty než NULL
.
V takových případech můžete předchozí příklad předat ISNULL()
funkce:
SELECT ISNULL(1 / NULLIF( 0, 0 ), 0);
Výsledek:
0
Zde jsem uvedl, že se má vrátit nula, kdykoli je výsledek NULL
.
Buďte však opatrní. V některých případech může být vrácení nuly nevhodné. Pokud se například zabýváte zásobami zásob, zadání nuly může znamenat, že neexistují žádné produkty, což nemusí být tento případ.
Možnost 3:Použijte CASE
Prohlášení
Dalším způsobem, jak to udělat, je použít CASE
prohlášení:
DECLARE @n1 INT = 20;
DECLARE @n2 INT = 0;
SELECT CASE
WHEN @n2 = 0
THEN NULL
ELSE @n1 / @n2
END
Výsledek:
NULL
Možnost 4:SET ARITHABORT
Prohlášení
SET ARITHABORT
příkaz ukončí dotaz, když během provádění dotazu dojde k chybě přetečení nebo dělení nulou. Můžeme jej použít ve spojení s SET ANSI WARNINGS
vrátíte NULL
kdykoli může dojít k chybě dělení nulou:
SET ARITHABORT OFF;
SET ANSI_WARNINGS OFF;
SELECT 20 / 0;
Výsledek:
NULL
Společnost Microsoft doporučuje, abyste vždy nastavili ARITHABORT
na ON
ve vašich přihlašovacích relacích a nastavením na OFF
může negativně ovlivnit optimalizaci dotazů, což vede k problémům s výkonem.
Někteří klienti (například SQL Server Management Studio) nastavují ARITHABORT
na ON
ve výchozím stavu. To je důvod, proč pravděpodobně nevidíte NULL
hodnota se vrací, když dělíte nulou. Můžete použít SET ARITHIGNORE
chcete-li toto chování změnit.
Možnost 5:SET ARITHIGNORE
Prohlášení
SET ARITHIGNORE
příkaz řídí, zda jsou během dotazu vráceny chybové zprávy z chyb přetečení nebo dělení nulou:
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;
Výsledek:
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.
Zde jsem nastavil ARITHABORT
a ANSI_WARNINGS
na OFF
takže příkaz nebyl kvůli chybě přerušen a NULL
je vráceno vždy, když dojde k chybě dělení nulou.
Všimněte si, že SET ARITHIGNORE
nastavení pouze řídí, zda se vrátí chybová zpráva. SQL Server vrátí NULL
ve výpočtu zahrnujícím chybu přetečení nebo dělení nulou, bez ohledu na toto nastavení.
Ve výše uvedeném příkladu můžeme vidět, že když ARITHIGNORE
je ON
, dělení nulovou chybou se nevrací. Když je OFF
, vrátí se chybová zpráva dělení nulou.