Tooprogram.ru

Компьютерный справочник
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Ошибка деления на ноль

Как избежать ошибки «деление на ноль» в SQL?

У меня есть это сообщение об ошибке:

Msg 8134, Уровень 16, состояние 1, Линия 1 делится на нулевую ошибку.

каков наилучший способ написать код SQL, чтобы я больше никогда не видел это сообщение об ошибке?

Я мог бы сделать одно из следующих действий:

  • добавьте предложение where, чтобы мой делитель никогда не был равен нулю
  • я мог бы добавить оператор case, так что есть особое отношение к нулю.

— лучший способ использовать NULLIF предложения?

есть ли лучший способ, или как это может быть реализовано?

17 ответов

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

но вот гораздо более приятный способ сделать это:

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

Если вы хотите вернуть ноль, в случае, если произойдет нулевое деление, вы можете использовать:

для каждого делителя, который равен нулю, вы получите ноль в результирующем наборе.

это казалось лучшим решением для моей ситуации при попытке решить деление на ноль, что происходит в моих данных.

Предположим, вы хотите рассчитать соотношение мужчин и женщин для различных школьных клубов, но вы обнаружите, что следующий запрос терпит неудачу и выдает ошибку деления на ноль, когда он пытается рассчитать соотношение для клуба «Властелин колец», в котором нет женщин:

вы можете использовать функцию NULLIF чтобы избежать деления на ноль. NULLIF сравнивает два выражения и возвращает нуль, если они равны или первое выражение в противном случае.

переписать запрос так:

любое число, разделенное на NULL дает NULL , и ошибка не генерируется.

вы также можете сделать это в начале запрос:

Так что если у вас есть что-то вроде 100/0 он вернет значение NULL. Я сделал это только для простых запросов, поэтому я не знаю, как это повлияет на более длинные/сложные.

изменить: Я получаю много downvotes на этом недавно. поэтому я подумал, что просто добавлю примечание, что этот ответ был написан до того, как вопрос прошел последнее редактирование, где возврат null был выделен как опция. что кажется вполне приемлемым. Некоторые из моих ответов были адресованы таким проблемам, как Эдвардо, в комментариях, который, казалось, выступал за возвращение 0. Это тот случай, против которого я выступал.

ответ: Я думаю, что здесь есть основная проблема, то есть деление на 0 не является законным. Это признак того, что что-то фундаментально неправильно. Если вы делите на ноль, вы пытаетесь сделать что-то, что не имеет смысла математически, поэтому никакой числовой ответ, который вы можете получить, не будет действительным. (Использование null в этом случае разумно, так как это не значение, которое будет использоваться в последующих математических расчетах).

поэтому Эдвардо спрашивает в комментариях: «что, если пользователь ставит 0?», и он выступает за то, чтобы получить 0 в ответ. Если пользователь помещает ноль в сумму, и вы хотите, чтобы 0 возвращалось, когда они это делают, то вы должны ввести код на уровне бизнес-правил, чтобы поймать это значение и вернуть 0. не имеют особого случая, когда деление на 0 = 0.

Это тонкая разница, но это важно. потому что в следующий раз, когда кто-то вызывает вашу функцию и ожидает, что она сделает правильную вещь, и она делает что-то фанки, что не является математически правильным, а просто обрабатывает конкретный случай edge у него есть хороший шанс укусить кого-нибудь позже. На самом деле вы не делите на 0. ты просто возвращаешь плохой ответ на плохой вопрос.

представьте, что я что-то кодирую, и я все испортил. Я должен был бы читать в значении масштабирования измерения излучения, но в странном случае края я не ожидал, я читал в 0. Затем я опускаю свою ценность в вашу функцию. ты возвращаешь мне ноль! Ура, никакой радиации! За исключением того, что это действительно там, и это просто то, что я передавал плохую ценность. но я понятия не иметь. Я хочу, чтобы подразделение выбросило ошибку, потому что это флаг, что что-то не так.

Читать еще:  Excessive deferral ошибки

вы можете, по крайней мере, остановить запрос от разрыва с ошибкой и вернуть NULL если есть деление на ноль:

, Я никогда преобразовать это в ноль с coalesce как показано в другой ответ, который получил много положительных отзывов. Это совершенно неправильно в математическом смысле, и это даже опасно, поскольку ваше приложение, вероятно, вернет неправильные и вводящие в заблуждение результаты.

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

замена «деления на ноль» на ноль является спорной, но это также не единственный вариант. В некоторых случаях замена на 1 (разумно) уместна. Я часто нахожу себя с помощью

когда я смотрю на сдвиги в баллах / подсчетах и хочу по умолчанию 1, Если у меня нет данных. Например

чаще всего я фактически рассчитал это соотношение где-то еще (не в последнюю очередь потому, что он может бросить некоторые очень большие коэффициенты регулировки для низких знаменатели. В этом случае я обычно контролирую для OldSampleScore больше порога; который затем исключает ноль. Но иногда «взлом» уместен.

Как в ячейке с формулой вместо ошибки показать 0

Случаются ситуации, когда в рабочей книге на листах создано много формул, выполняющих различные задачи. При этом формулы созданы когда-то давно, возможно даже на вами. И формулы возвращают ошибки. Например #ДЕЛ/0! (#DIV/0!) . Эта ошибка возникает, если внутри формулы происходит деление на ноль: = A1 / B1 , где в B1 ноль или пусто. Но могут быть и другие ошибки(#Н/Д, #ЗНАЧ! и т.д.). Можно изменить формулу, добавив проверку на ошибку:
=ЕСЛИ(ЕОШ( A1 / B1 );0; A1 / B1 )
=IF(ISERR( A1 / B1 ),0, A1 / B1 )
аргументы:
=ЕСЛИ(ЕОШ(1 аргумент);2 аргумент; 1 аргумент)
Эти формулы будут работать в любой версии Excel. Правда, функция ЕОШ не обработает ошибку #Н/Д (#N/A) . Чтобы так же обработать и #Н/Д необходимо использовать функцию ЕОШИБКА:
=ЕСЛИ(ЕОШИБКА( A1 / B1 );0; A1 / B1 )
=IF(ISERROR( A1 / B1 ),0, A1 / B1 )
Однако далее по тексту я буду применять ЕОШ(т.к. она короче) и к тому же не всегда надо «не видеть» ошибки #Н/Д.
Но для версий Excel 2007 и выше можно применить чуть более оптимизированную функцию ЕСЛИОШИБКА (IFERROR) :
=ЕСЛИОШИБКА( A1 / B1 ;0)
=IFERROR( A1 / B1 ,0)
аргументы:
=ЕСЛИОШИБКА(1 аргумент; 2 аргумент)

1 аргумент: выражение для вычисления
2 аргумент: значение или выражение, которое необходимо вернуть в ячейку в случае ошибки в первом аргументе.

Почему ЕСЛИОШИБКА лучше и я называю её более оптимизированной? Разберем первую формулу подробнее:
=ЕСЛИ(ЕОШ( A1 / B1 );0; A1 / B1 )
Если вычислить пошагово, то увидим, что сначала происходит вычисление выражения A1 / B1 (т.е. деление). И если его результат ошибка – то ЕОШ вернет ИСТИНА (TRUE) , которое будет передано в ЕСЛИ (IF) . И тогда функцией ЕСЛИ(IF) будет возвращено значение из второго аргумента 0.
Но если результат не является ошибочным и ЕОШ (ISERR) возвращает ЛОЖЬ (FALSE) – то функция заново будет вычислять уже вычисленное ранее выражение: A1 / B1
С приведенной формулой это особой роли не играет. Но если применяется формула вроде ВПР (VLOOKUP) с просмотром на несколько тысяч строк – то вычисление два раза может значительно увеличить время пересчета формул.
Функция же ЕСЛИОШИБКА (IFERROR) один раз вычисляет выражение, запоминает его результат и если он ошибочен возвращает записанное вторым аргументом. Если же ошибки нет, то возвращает запомненный результат вычисления выражения из первого аргумента. Т.е. вычисление по факту происходит один раз, что практически не будет влиять на скорость общего пересчета формул.
Поэтому если у вас Excel 2007 и выше и файл не будет использоваться в более ранних версиях – то имеет смысл использовать именно ЕСЛИОШИБКА (IFERROR) .

Для чего формулы с ошибками вообще исправлять? Обычно делается для более эстетичного отображения данных в отчетах, особенно если отчеты потом руководству отправляют.

Читать еще:  Не устанавливается приложение ошибка 24

Итак, есть на листе такие формулы, ошибки которых надо обработать. Если подобных формул для исправления одна-две(да даже 10-15) – то проблем почти нет заменить вручную. Но если таких формул несколько десятков, а то и сотен – проблема приобретает почти вселенские масштабы :-). Однако процесс можно упростить через написание относительно простого кода Visual Basic for Application.
Для всех версий Excel:

Sub IfIsErrNull() Const sToReturnVal As String = «0» ‘если необходимо вместо нуля возвращать пусто ‘Const sToReturnVal As String = «»»»»» Dim rr As Range, rc As Range Dim s As String, ss As String On Error Resume Next Set rr = Intersect(Selection, ActiveSheet.UsedRange) If rr Is Nothing Then MsgBox «Выделенный диапазон не содержит данных», vbInformation, «www.excel-vba.ru» Exit Sub End If For Each rc In rr If rc.HasFormula Then s = rc.Formula s = M If Left(s, 9) <> «IF(ISERR(» Then If rc.HasArray Then rc.FormulaArray = ss Else rc.Formula = ss End If If Err.Number Then ss = rc.Address rc.Select Exit For End If End If End If Next rc If Err.Number Then MsgBox «Невозможно преобразовать формулу в ячейке: » & ss & vbNewLine & _ Err.Description, vbInformation, «www.excel-vba.ru» Else MsgBox «Формулы обработаны», vbInformation, «www.excel-vba.ru» End If End Sub

Для версий 2007 и выше

Sub IfErrorNull() Const sToReturnVal As String = «0» ‘если необходимо вместо нуля возвращать пусто ‘Const sToReturnVal As String = «»»»»» Dim rr As Range, rc As Range Dim s As String, ss As String On Error Resume Next Set rr = Intersect(Selection, ActiveSheet.UsedRange) If rr Is Nothing Then MsgBox «Выделенный диапазон не содержит данных», vbInformation, «www.excel-vba.ru» Exit Sub End If For Each rc In rr If rc.HasFormula Then s = rc.Formula s = M If Left(s, 8) <> «IFERROR(» Then If rc.HasArray Then rc.FormulaArray = ss Else rc.Formula = ss End If If Err.Number Then ss = rc.Address rc.Select Exit For End If End If End If Next rc If Err.Number Then MsgBox «Невозможно преобразовать формулу в ячейке: » & ss & vbNewLine & _ Err.Description, vbInformation, «www.excel-vba.ru» Else MsgBox «Формулы обработаны», vbInformation, «www.excel-vba.ru» End If End Sub

Как это работает
Если не знакомы с макросами, то для начала лучше прочитать как их создавать и вызывать: Что такое макрос и где его искать?, т.к. может случиться так, что все сделаете правильно, но забудете макросы разрешить и ничего не заработает.

Копируете приведенный код, переходите в редактор VBA(Alt+F11), создаете стандартный модуль(InsertModule) и просто вставляете в него этот код. Переходите в нужную книгу Excel и выделяете все ячейки, формулы в которых необходимо преобразовать таким образом, чтобы в случае ошибки они возвращали ноль. Жмете Alt+F8, выбираете код IfIsErrNull(или IfErrorNull, в зависимости от того, какой именно скопировали) и жмете Выполнить.
Ко всем формулам в выделенных ячейках будет добавлена функция обработки ошибки. Приведенные коды учитывают так же:
-если в формуле уже применена функция ЕСЛИОШИБКА или ЕСЛИ(ЕОШ, то такая формула не обрабатывается;
-код корректно обработает так же функции массива;
-выделять можно несмежные ячейки(через Ctrl).
В чем недостаток: сложные и длинные формулы массива могут вызвать ошибку кода, в связи с особенностью данных формул и их обработкой из VBA. В таком случае код напишет о невозможности продолжить работу и выделит проблемную ячейку. Поэтому настоятельно рекомендую производить замены на копиях файлов.
Если значение ошибки надо заменить на пусто, а не на ноль, то надо строку

Const sToReturnVal As String = «0»

Удалить, а перед строкой

‘Const sToReturnVal As String = «»»»»»

Удалить апостроф ( )

Так же можно данный код вызывать нажатием кнопки(Как создать кнопку для вызова макроса на листе) или поместить в надстройку(Как создать свою надстройку?), чтобы можно было вызывать из любого файла.

И небольшое дополнение: старайтесь применять код вдумчиво. Не всегда возврат ошибки мешает. Например, при использовании ВПР иногда полезно видеть какие значения не были найдены.
Так же хочу отметить, что применять надо к реально работающим формулам. Потому как если формула возвращает #ИМЯ!(#NAME!), то это означает, что в формуле неверно записан какой-то аргумент и это ошибка записи формулы, а не ошибка результата вычисления. Такие формулы лучше проанализировать и найти ошибку, чтобы избежать логических ошибок расчетов на листе.

Читать еще:  Ошибка при запуске приложения 0

Статья помогла? Поделись ссылкой с друзьями!

Почему делить на ноль нельзя?

Все математические действия равны, но некоторые равнее других

Начнём с того, что четыре арифметических действия — сложение, вычитание, умножение и деление — не являются равноправными. И разговор идёт не о порядке выполнения действий при решении какого-нибудь примера или уравнения. Нет, имеется в виду само понятие числа. И согласно ему, наиболее важными являются сложение и умножение. А уже вычитание и деление «вытекают» из них тем или иным образом.

Сложение и вычитание

Например, разберём простую операцию: «3 — 1». Что это означает? Школьник легко объяснит эту задачку: это означает, что было три предмета (например, три апельсина), один вычли, оставшееся количество предметов и есть верный ответ. Верно описано? Верно. Мы и сами объяснили бы точно так же. Но математики рассматривают процесс вычитания иначе.

Операция «3 — 1» рассматривается не с позиции вычитания, а только со стороны сложения. Согласно этому нет никаких «три минус один», есть «какое-то неизвестное число, которое при прибавлении одного даёт три». Таким образом, простое «три минус один» превращается в уравнение с одним неизвестным: «х + 1 = 3». Причём появление уравнения изменило знак — вычитание поменялось на сложение. Осталась только одна задача — отыскать подходящее число.

Умножение и деление

Аналогичные метаморфозы происходят с таким действием, как деление. Задачу «6 : 3» математики отказываются воспринимать как некие шесть предметов, разбитых на три части. «Шесть разделить на три» не что иное, как «неизвестное число, умноженное на три, в результате чего получилось шесть»: «х · 3».

Делим на ноль

Выяснив принцип математических действий по отношению к задачам с вычитанием и делением, рассмотрим наше деление на ноль.

Задача «4 : 0» превращается в «х · 0». Получается, нам нужно найти такое число, умножение с которым даст нам 4. Известно, что умножение на ноль всегда даёт ноль. Это уникальное свойство нуля и, собственно, его суть. Числа, умноженного на ноль и выдающего любое другое число кроме нуля, не существует. Мы пришли к противоречию, значит задача не имеет решения. Следовательно, записи «4 : 0» не соответствует никакое определённое число, а отсюда уже вытекает её бессмысленность. Поэтому, чтобы кратко подчеркнуть непродуктивность такого процесса, как деление на ноль, и говорят, что «на ноль делить нельзя».

Больше интересных материалов:

А что получится, если ноль разделить на ноль?

Представим такое уравнение: «0 · x = 0». С одной стороны, выглядит вполне справедливо. Представляем вместо неизвестного числа ноль и получаем готовое решение: «0 · 0 = 0». Из этого вполне логично вывести, что «0 : 0 = 0».

Однако теперь давайте в это же уравнение с неизвестным вместо «x = 0» подставим любое другое число, например «x = 7». Получившееся выражение выглядит теперь как «0 · 7 = 0». Вроде бы, всё верно. Делаем обратную операцию и получаем «0 : 0 = 7». Но тогда, получается, что можно взять абсолютно любое число и вывести 0 : 0 = 1, 0 : 0 = 2. 0 : 0 = 145. — и так до бесконечности.

Если при любом числе х уравнение будет справедливо, то мы не имеем права выбрать лишь одно, исключив остальные. Значит, мы так и не можем ответить, какому числу соответствует выражение «0 : 0». Снова оказавшись в тупике, мы признаём, что и эта операция тоже бессмысленна. Получается, что ноль нельзя делить даже на самого себя.

Оговоримся, что в математическом анализе иногда бывают специальные условия задачи — так называемое «раскрытие неопределенности». В подобных случаях разрешается отдавать предпочтение одному из возможных решений уравнения «0 · x = 0». Однако в арифметике таких «допусков» не происходит.

Ссылка на основную публикацию
Adblock
detector