Как избежать, “делятся на нулевую” ошибку в SQL?

Просто используйте перегрузку конструктора std::vector, которая принимает два итератора, для создания временного:

 Method( {myVec.begin(), myVec.end()} )

Вы можете также объявить перегрузку Method(), которая принимает вектор производных указателей, для удобства и просто делает это. Это предотвратит некоторое раздувание кода, когда это делается часто.

337
задан DineshDB 27 March 2018 в 20:36
поделиться

9 ответов

Чтобы избежать ошибки «Деление на ноль», мы запрограммировали это следующим образом:

Select Case when divisor=0 then null
Else dividend / divisor
End ,,,

Но вот способ сделать это гораздо лучше:

Select dividend / NULLIF(divisor, 0) ...

Теперь единственная проблема - запомнить бит NullIf, если я использую клавишу "/".

600
ответ дан 23 November 2019 в 00:39
поделиться

Вот как я это исправил:

IIF (ValueA! = 0, Total / ValueA, 0)

Может быть добавлено в обновление:

SET Pct = IIF (ValueA! = 0, Total / ValueA, 0)

Или в выборе:

SELECT IIF (ValueA! = 0, Total / ValueA, 0) AS Pct FROM из имени таблицы ;

Мысли?

0
ответ дан 23 November 2019 в 00:39
поделиться

Отфильтруйте данные при использовании предложения where, чтобы не получить значения 0.

2
ответ дан 23 November 2019 в 00:39
поделиться

Не существует волшебной глобальной настройки «отключить деление на 0 исключений». Операция должна быть выбрана, так как математическое значение x / 0 отличается от значения NULL, поэтому она не может вернуть NULL. I assume you are taking care of the obvious and your queries have conditions that should eliminate the records with the 0 divisor and never evaluate the division. The usual 'gotcha' is than most developers expect SQL to behave like procedural languages and offer logical operator short-circuit, but it does NOT. I recommend you read this article: http://www.sqlmag.com/Articles/ArticleID/9148/pg/2/2.html

3
ответ дан 23 November 2019 в 00:39
поделиться

РЕДАКТИРОВАТЬ: 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.

32
ответ дан 23 November 2019 в 00:39
поделиться

Некоторое время назад я написал функцию для ее обработки для моих хранимых процедур :

print 'Creating safeDivide Stored Proc ...'
go

if exists (select * from dbo.sysobjects where  name = 'safeDivide') drop function safeDivide;
go

create function dbo.safeDivide( @Numerator decimal(38,19), @divisor decimal(39,19))
   returns decimal(38,19)
begin
 -- **************************************************************************
 --  Procedure: safeDivide()
 --     Author: Ron Savage, Central, ex: 1282
 --       Date: 06/22/2004
 --
 --  Description:
 --  This function divides the first argument by the second argument after
 --  checking for NULL or 0 divisors to avoid "divide by zero" errors.
 -- Change History:
 --
 -- Date        Init. Description
 -- 05/14/2009  RS    Updated to handle really freaking big numbers, just in
 --                   case. :-)
 -- 05/14/2009  RS    Updated to handle negative divisors.
 -- **************************************************************************
   declare @p_product    decimal(38,19);

   select @p_product = null;

   if ( @divisor is not null and @divisor <> 0 and @Numerator is not null )
      select @p_product = @Numerator / @divisor;

   return(@p_product)
end
go
6
ответ дан 23 November 2019 в 00:39
поделиться
SELECT Dividend / ISNULL(NULLIF(Divisor,0), 1) AS Result from table

Поймав ноль с помощью nullif (), а затем получив нулевое значение с помощью isnull (), вы можете обойти свое деление с помощью ошибки нуля.

26
ответ дан 23 November 2019 в 00:39
поделиться
  1. Добавьте ограничение CHECK, которое заставляет Divisor быть ненулевым
  2. Добавьте валидатор в форму, чтобы пользователь не мог вводить нулевые значения в это поле.
4
ответ дан 23 November 2019 в 00:39
поделиться

Вот ситуация, когда можно разделить на ноль. Бизнес-правило заключается в том, что для расчета оборачиваемости запасов вы берете стоимость товаров, проданных за период, и переводите ее в годовом исчислении. Получив годовое число, вы делите его на средний запас за период.

Я собираюсь подсчитать количество оборотов товарных запасов за трехмесячный период. Я подсчитал, что у меня стоимость проданных товаров за трехмесячный период составляет 1000 долларов. Годовая норма продаж составляет 4000 долларов США (1000 долларов США / 3 шт.) * 12. Начальный запас равен 0. Конечный запас равен 0. Мой средний запас сейчас равен 0. У меня продажи составляют 4000 долларов в год, а запасов нет. Это дает бесконечное количество оборотов. Это означает, что весь мой инвентарь конвертируется и покупается покупателями.

Это бизнес-правило расчета оборачиваемости запасов.

3
ответ дан 23 November 2019 в 00:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: