EDIT:
I’m getting a lot of downvotes on this recently…so I thought I’d just add a note that this answer was written before the question underwent it’s most recent edit, where returning null was highlighted as an option…which seems very acceptable. Some of my answer was addressed to concerns like that of Edwardo, in the comments, who seemed to be advocating returning a 0. This is the case I was railing against.
ANSWER:
I think there’s an underlying issue here, which is that division by 0 is not legal. It’s an indication that something is fundementally wrong. If you’re dividing by zero, you’re trying to do something that doesn’t make sense mathematically, so no numeric answer you can get will be valid. (Use of null in this case is reasonable, as it is not a value that will be used in later mathematical calculations).
So Edwardo asks in the comments «what if the user puts in a 0?», and he advocates that it should be okay to get a 0 in return. If the user puts zero in the amount, and you want 0 returned when they do that, then you should put in code at the business rules level to catch that value and return 0…not have some special case where division by 0 = 0.
That’s a subtle difference, but it’s important…because the next time someone calls your function and expects it to do the right thing, and it does something funky that isn’t mathematically correct, but just handles the particular edge case it’s got a good chance of biting someone later. You’re not really dividing by 0…you’re just returning an bad answer to a bad question.
Imagine I’m coding something, and I screw it up. I should be reading in a radiation measurement scaling value, but in a strange edge case I didn’t anticipate, I read in 0. I then drop my value into your function…you return me a 0! Hurray, no radiation! Except it’s really there and it’s just that I was passing in a bad value…but I have no idea. I want division to throw the error because it’s the flag that something is wrong.
Stuck with ‘SQL server divide by zero error encountered’? We can help you.
Recently, one of our customer came across this error as it is not possible to divide a number by zero. It leads to infinity. We perform data calculations in SQL Server for various considerations.
As part of your Server Management Services, we assist our customers with several SQL queries.
Today, let us see how to fix this error.
Cause for the error ‘SQL Server divide by zero error encountered’
Let us see what could cause the error ‘SQL Server divide by zero error encountered’.
To start with, If the product2 quantity goes out of stock and that means we do not have any quantity for product2.
DECLARE @Product1 INT;
DECLARE @Product2 INT;
SET @Product1 = 50;
SET @Product2 = 0;
SELECT @Product1 / @Product2 ProductRatio;
We get SQL divide by zero error messages (message id 8134, level 16):
Msg 8134, Level 16, State 1, Line 13
Divide by zero error encountered.
How to solve the error ‘SQL Server divide by zero error encountered’?
Always, it is a best practice to write code in such a way that it does not give divide by zero message. It should have a mechanism to deal proactively with such conditions.
Moving ahead, let us see an effective methods followed by our Support Techs employ in order to solve this error.
Method 1: SQL NULLIF Function
Initially, we use NULLIF function to avoid divide by zero error message.
The syntax of NULLIF function:
NULLIF(expression1, expression2)
It accepts two arguments.
- Firstly, If both the arguments are equal, it returns a null value
For example, suppose that the value of both arguments is 10.
SELECT NULLIF(10, 10) result;
In this case, the output will be null.
- Secondly, If both the arguments are not equal, it returns the value of the first argument.
In this example, both argument values differ. It returns the output as value of first argument 10.
SELECT NULLIF(10, 5) result;
We can modify our initial query using the SQL NULLIF statement. We place the following logic using NULLIF function for eliminating SQL divide by zero error:
- Use NULLIF function in the denominator with second argument value zero
- If the value of the first argument is also zero, this function returns a null value. In SQL Server, if we divide a number with null, the output is null as well.
- If the value of the first argument is not zero, it returns the first argument value and division takes place as standard values.
DECLARE @Product1 INT;
DECLARE @Product2 INT;
SET @Product1 = 50;
SET @Product2 = 0;
SELECT @Product1 / NULLIF(@Product2,0) ProductRatio;
Execute this modified query. We will get the output as NULL because denominator contains value zero.
If we do not want null value in the output, we can use SQL ISNULL function to avoid null values in the output and display a definite value. This function replaces the null value in the expression1 and returns expression2 value as output.
Method 2: Using CASE statement to avoid divide by zero error
Secondly, you can use a CASE statement in SQL to return values based on specific conditions. The Case statement checks for the value of @Product2 parameter:
- If the @Product2 value is zero, it returns null.
- If the above condition is not satisfied, it does the arithmetic operation (@Product1/@Product2) and returns the output.
DECLARE @Product1 INT;
DECLARE @Product2 INT;
SET @Product1 = 50;
SET @Product2 = 0;
SELECT CASE
WHEN @Product2 = 0
THEN NULL
ELSE @Product1 / @Product2
END AS ProductRatio;
We will get output as NULL.
Method 3: SET ARITHABORT OFF
By default, SQL Server has a default value of SET ARITHABORT is ON. We get SQL divide by zero error in the output using the default behavior.
The T-SQL syntax for controlling the ARITHABORT option is shown below:
SET ARITHABORT { ON | OFF }
- Using ARITHABORT ON, the query will terminate with divide by zero message. It is the default behavior.
SET ARITHABORT ON — Default
SET ANSI_WARNINGS ON
DECLARE @Product1 INT;
DECLARE @Product2 INT;
SET @Product1 = 50;
SET @Product2 = 0;
SELECT @Product1 / @Product2 ProductRatio;
We get the SQL divide by zero error messages.
- Using ARITHABORT OFF, the batch will terminate and returns a null value. We need to use ARITHABORT in combination with SET ANSI_WARNINGS OFF to avoid the error message:
SET ARITHABORT OFF
SET ANSI_WARNINGS OFF
DECLARE @Product1 INT;
DECLARE @Product2 INT;
SET @Product1 = 50;
SET @Product2 = 0;
SELECT @Product1 / @Product2 ProductRatio;
We will get the output as NULL.
Finally, you can use the following query to check the current setting for the ARITHABORT parameter:
DECLARE @ARITHABORT VARCHAR(3) = ‘OFF’;
IF ( (64 & @@OPTIONS) = 64 ) SET @ARITHABORT = ‘ON’;
SELECT @ARITHABORT AS ARITHABORT;
The default ARITHABORT setting for SQL Server Management Studio (SSMS) is ON. We can view it using SSMS Tools properties. Navigate to Tools -> Options -> Advanced.
We should not modify the value of ARITHABORT unless required. It might create performance issues, as well. It is better to use other methods for avoiding SQL divide by zero error.
[Need assistance? We can help you]
Conclusion
In short, we saw how our Support Techs resolve error ‘SQL Server divide by zero error encountered’
Are you using Docker based apps?
There are proven ways to get even more out of your Docker containers! Let us help you.
Spend your time in growing business and we will take care of Docker Infrastructure for you.
GET STARTED
var google_conversion_label = «owonCMyG5nEQ0aD71QM»;
Here are five options for dealing with error Msg 8134 “Divide by zero error encountered” in SQL Server.
First, here’s an example of code that produces the error we’re talking about:
SELECT 1 / 0;
Result:
Msg 8134, Level 16, State 1, Line 1 Divide by zero error encountered.
We get the error because we’re trying to divide a number by zero. Mathematically, this does not make any sense. You can’t divide a number by zero and expect a meaningful result.
To deal with this error, we need to decide what should be returned when we try to divide by zero. For example, we might want a null value to be returned. Or we might want zero to be returned. Or some other value.
Below are some options for dealing with this error.
Option 1: The NULLIF()
Expression
A quick and easy way to deal with this error is to use the NULLIF()
expression:
SELECT 1 / NULLIF( 0, 0 );
Result:
NULL
NULLIF()
returns NULL
if the two specified expressions are the same value. It returns the first expression if the two expressions are different. Therefore, if we use zero as the second expression, we will get a null value whenever the first expression is zero. Dividing a number by NULL
results in NULL
.
Actually, SQL Server already returns NULL
on a divide-by-zero error, but in most cases we don’t see this, due to our ARITHABORT
and ANSI_WARNINGS
settings (more on this later).
Option 2: Add the ISNULL()
Function
In some cases, you might prefer to return a value other than NULL
.
In such cases, you can pass the previous example to the ISNULL()
function:
SELECT ISNULL(1 / NULLIF( 0, 0 ), 0);
Result:
0
Here I specified that zero should be returned whenever the result is NULL
.
Be careful though. In some cases, returning zero might be inappropriate. For example, if you’re dealing with inventory supplies, specifying zero might imply that there are zero products, which might not be the case.
Option 3: Use a CASE
Statement
Another way to do it is to use a CASE
statement:
DECLARE @n1 INT = 20;
DECLARE @n2 INT = 0;
SELECT CASE
WHEN @n2 = 0
THEN NULL
ELSE @n1 / @n2
END
Result:
NULL
Option 4: The SET ARITHABORT
Statement
The SET ARITHABORT
statement ends a query when an overflow or divide-by-zero error occurs during query execution. We can use it in conjunction with SET ANSI WARNINGS
to return NULL
whenever the divide-by-zero error might occur:
SET ARITHABORT OFF;
SET ANSI_WARNINGS OFF;
SELECT 20 / 0;
Result:
NULL
Microsoft recommends that you always set ARITHABORT
to ON
in your logon sessions, and that setting it to OFF
can negatively impact query optimisation, leading to performance issues.
Some clients (such as SQL Server Management Studio) set ARITHABORT
to ON
by default. This is why you probably don’t see the NULL
value being returned when you divide by zero. You can use SET ARITHIGNORE
to change this behaviour if you prefer.
Option 5: The SET ARITHIGNORE
Statement
The SET ARITHIGNORE
statement controls whether error messages are returned from overflow or divide-by-zero errors during a query:
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;
Result:
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.
Here, I set ARITHABORT
and ANSI_WARNINGS
to OFF
so that the statement wasn’t aborted due to the error, and NULL
is returned whenever there’s a divide-by-zero error.
Note that the SET ARITHIGNORE
setting only controls whether an error message is returned. SQL Server returns a NULL
in a calculation involving an overflow or divide-by-zero error, regardless of this setting.
In the above example we can see that when ARITHIGNORE
is ON
, the division by zero error is not returned. When it’s OFF
, the division by zero error message is returned.
Время прочтения: 4 мин.
В процессе работы c данными в SQL Server, мы столкнулись с такой ситуацией. Одним из промежуточных шагов в нашей задаче было выполнение простого арифметического действия, из данных в виде целых чисел, загружаемых в таблицу SQL, значения которых участвовали в делении. В какой-то момент времени выполнение всего кода могло быть прервано сообщением об ошибке из-за того, что знаменатель принимал значение 0. Как этого избежать подобной ситуации, я расскажу в этой статье.
Обычно при делении не возникает проблем, и мы получаем соотношение двух величин, если знаменатель не равен нулю:
declare @vol_1 int;
declare @vol_2 int;
set @vol_1 = 10;
set @vol_2 = 5;
select @vol_1/@vol_2 ratio_vol;
Соотношение значений вычисляется корректно:
При значении @vol_2 = 0 получаем сообщение об ошибке:
declare @vol_1 int;
declare @vol_2 int;
set @vol_1 = 10;
set @vol_2 = 0;
select @vol_1/@vol_2 ratio_vol;
Для того, чтобы ошибка не возникала при выполнении запроса предлагается предусмотреть механизм, позволяющий справляться с условием, когда значение @vol_2 станет равным нулю
1. Применение функции NULLIF.
Синтаксис NULLIF следующий:
NULLIF(expr1, expr2)
При равенстве значений двух аргументов, возвращается значение NULL.
Например:
select NULLIF (55, 55) result;
Результат запроса:
Если значения аргументов не равны, возвращается значение первого аргумента (expr1).
select NULLIF (12, 55) result;
Изменим этот запрос, добавив в него NULLIF, для обхода ошибки деления на ноль.
Логика использования функции NULLIF для задачи деления на ноль следующая:
- используем в знаменателе функцию NULLIF с нулевым значением ее второго аргумента
- если значение первого аргумента функции NULLIF также равно нулю, то возвращается значение NULL, и тогда в SQL Server, если мы разделим число на значение NULL, на выходе получим NULL.
- если значение первого аргумента не равно нулю, возвращается значение первого аргумента функции NULLIF, и деление выполняется как стандартная операция деления.
declare @vol_1 int;
declare @vol_2 int;
set @vol_1 = 10;
set @vol_2 = 0;
select @vol_1/NULLIF (@vol_2, 0) ratio_vol;
Ниже, результат работы такого кода (в знаменателе – значение NULL):
Добавим в код функцию ISNULL, для того, чтобы вместо значения NULL в выводе результата вычисления получать 0.
Эта функция заменяет NULL значение в expr1 и возвращает значение expr2 в качестве вывода.
Логика запроса с функциями ISNULL и NULLIF такая:
- первый аргумент ((@vol_1/ NULLIF (@vol_2,0)) вернет значение NULL;
- для функции ISNULL указываем нулевое значение второго аргумента;
- так как первый аргумент — NULL, то вывод всего запроса равен нулю, т.е. значению второго аргумента.
Пример кода с функциями ISNULL и NULLIF:
declare @vol_1 int;
declare @vol_2 int;
set @vol_1 = 10;
set @vol_2 = 0;
select ISNULL (@vol_1/NULLIF (@vol_2, 0),0) ratio_vol;
Вывод результата успешного выполнения запроса:
2. Использование оператора CASE.
Посмотрим, как использовать для нашей задачи оператор CASE для возврата значений на основе определенных условий.
Оператор CASE проверит значение параметра @vol_2:
- если значение @vol_2 равно нулю, возвращается значение NULL;
- если это условие не выполняется, то производится арифметическая операция деления (@vol_1/@vol_2) и возвращается ее результат.
declare @vol_1 int;
declare @vol_2 int;
set @vol_1 = 10;
set @vol_2 = 0;
select CASE
when @vol_2 = 0
then NULL
else @vol_1/@vol_2
end as ratio_vol;
Успешный результат запроса:
Применяя рассмотренные методы, позволяющие избежать ошибки деления на ноль в SQL Server, можно быть уверенным в том, что этот специфический, с точки зрения арифметики, код, являющийся частью большей задачи, не даст сбой в результате ее решения.
Проблемы
Предположим, что в SQL Server 2017 г. в системе с занятой работой выполняется множество параллельных запросов. При выполнении параллельного запроса можно заметить, что параллельный запрос принудительно выполняется в последовательном режиме из-за отсутствия параллельных рабочих потоков. В этом случае функция предупреждения об использовании предоставления памяти может вызвать ошибку деления на ноль.
Решение
Эта проблема устранена в следующем накопительном обновлении для SQL Server:
Накопительный пакет обновления 1 для SQL Server 2017
Каждое новое накопительное обновление для SQL Server содержит все исправления и все исправления для системы безопасности, которые были включены в предыдущее накопительное обновление. Ознакомьтесь с последними накопительными обновлениями для SQL Server:
Последнее накопительное обновление для SQL Server 2017
Статус
Корпорация Майкрософт подтверждает наличие этой проблемы в своих продуктах, которые перечислены в разделе «Применяется к».
Ссылки
Сведения о терминологии, которую корпорация Майкрософт использует для описания обновлений программного обеспечения.
Нужна дополнительная помощь?
Нужны дополнительные параметры?
Изучите преимущества подписки, просмотрите учебные курсы, узнайте, как защитить свое устройство и т. д.
В сообществах можно задавать вопросы и отвечать на них, отправлять отзывы и консультироваться с экспертами разных профилей.