Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

5 начина да коригирате грешката „Деление на нула“ в SQL Server (Msg 8134)

Ето пет опции за справяне с грешка Msg 8134 „Открита е грешка при разделяне на нула“ в SQL Server.

Грешката

Първо, ето пример за код, който произвежда грешката, за която говорим:

SELECT 1 / 0;

Резултат:

Msg 8134, Level 16, State 1, Line 1
Divide by zero error encountered.

Получаваме грешката, защото се опитваме да разделим число на нула. Математически това няма никакъв смисъл. Не можете да разделите число на нула и да очаквате смислен резултат.

За да се справим с тази грешка, трябва да решим какво трябва да бъде върнато, когато се опитаме да разделим на нула. Например, може да искаме да бъде върната нулева стойност. Или може да искаме нула да бъде върната. Или някаква друга стойност.

По-долу са някои опции за справяне с тази грешка.

Опция 1:NULLIF() Израз

Бърз и лесен начин за справяне с тази грешка е да използвате NULLIF() израз:

SELECT 1 / NULLIF( 0, 0 );

Резултат:

NULL

NULLIF() връща NULL ако двата посочени израза са с една и съща стойност. Връща първия израз, ако двата израза са различни. Следователно, ако използваме нула като втори израз, ще получим нулева стойност, когато първият израз е нула. Разделяне на число на NULL води до NULL .

Всъщност SQL Server вече връща NULL при грешка при деление на нула, но в повечето случаи не виждаме това, поради нашия ARITHABORT и ANSI_WARNINGS настройки (повече за това по-късно).

Опция 2:Добавете ISNULL() Функция

В някои случаи може да предпочетете да върнете стойност, различна от NULL .

В такива случаи можете да предадете предишния пример на ISNULL() функция:

SELECT ISNULL(1 / NULLIF( 0, 0 ), 0);

Резултат:

0

Тук уточних, че нула трябва да се връща винаги, когато резултатът е NULL .

Бъдете внимателни все пак. В някои случаи връщането на нула може да е неподходящо. Например, ако имате работа с инвентарни запаси, посочването на нула може да означава, че има нулеви продукти, което може да не е така.

Вариант 3:Използвайте CASE Изявление

Друг начин да го направите е да използвате CASE изявление:

DECLARE @n1 INT = 20;
DECLARE @n2 INT = 0;

SELECT CASE
    WHEN @n2 = 0
    THEN NULL
    ELSE @n1 / @n2
END

Резултат:

NULL

Опция 4:SET ARITHABORT Изявление

SET ARITHABORT оператор завършва заявка, когато възникне грешка при препълване или деление на нула по време на изпълнение на заявката. Можем да го използваме във връзка с SET ANSI WARNINGS за да върнете NULL всеки път, когато може да възникне грешка при деление на нула:

SET ARITHABORT OFF;
SET ANSI_WARNINGS OFF;
SELECT 20 / 0;

Резултат:

NULL

Microsoft препоръчва винаги да задавате ARITHABORT до ON във вашите сесии за влизане и това да го настроите на OFF може да повлияе негативно на оптимизирането на заявките, което води до проблеми с производителността.

Някои клиенти (като SQL Server Management Studio) задават ARITHABORT до ON по подразбиране. Ето защо вероятно не виждате NULL стойност, която се връща, когато разделите на нула. Можете да използвате SET ARITHIGNORE за да промените това поведение, ако предпочитате.

Опция 5:SET ARITHIGNORE Изявление

SET ARITHIGNORE операторът контролира дали съобщенията за грешка се връщат от грешки при препълване или деление на нула по време на заявка:

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;

Резултат:

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.

Тук задавам ARITHABORT и ANSI_WARNINGS до OFF така че изявлението да не е прекратено поради грешката и NULL се връща всеки път, когато има грешка при деление на нула.

Обърнете внимание, че SET ARITHIGNORE настройката контролира само дали се връща съобщение за грешка. SQL Server връща NULL при изчисление, включващо грешка при препълване или деление на нула, независимо от тази настройка.

В горния пример можем да видим, че когато ARITHIGNORE е ON , грешката при деление на нула не се връща. Когато е OFF , се връща съобщението за грешка при деленето на нула.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Използвайте sys.trigger_event_types, за да изброите типовете тригерни събития в SQL Server

  2. Периодични повреди на ODBC връзката

  3. pyodbc.connect() работи, но не и sqlalchemy.create_engine().connect()

  4. Свързване с локална база данни на SQL Server с помощта на C#

  5. Какви са разликите между Merge Join и Lookup трансформациите в SSIS?