SQL Server - ошибка деления на ноль в предложении WHERE (даже при условии делителя> 0) - PullRequest
0 голосов
/ 04 октября 2018

При тестировании SQL-запроса с предложением WHERE, связанным с делением, я обнаружил странную ошибку.Задача состоит в том, чтобы найти ошибки в счете-фактуре, где любой из следующих условий:

  • Либо Amount, либо Tax равен нулю (не оба);
  • Оба Amount и Tax не равны нулю, но они не удовлетворяют определенному арифметическому условию.

Итак, запрос, который я пришел, выглядит следующим образом:

SELECT InvoiceNumber, InvoiceDate, Amount, Tax
FROM Invoices
    WHERE (Amount <> 0 AND Tax = 0)
    OR (Amount = 0 AND Tax <> 0)
    OR (Amount <> 0 AND Tax <> 0 AND ABS(Tax / Amount - 0.18) > 0.005)

Что еще более странно, этот запрос работает нормально:

SELECT InvoiceNumber, InvoiceDate, Amount, Tax
FROM Invoices
    WHERE Amount <> 0 AND Tax <> 0 AND ABS(Tax / Amount - 0.18) > 0.005

Я полагаю, что булево вычисление в условных предложениях SQL Server не работает, как в C # (где я мог бы ожидать, что ленивая оценка предотвращает деление на ноль, ошибка).

Как сделать этот запрос корректным?

ПРИМЕЧАНИЕ: Есть десятки миллионов записей, поэтому вложенные операторы SELECTможет повлиять на производительность.

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Не зависит от порядка оценки предложений или условий в запросе.Период. Оптимизатор оставляет за собой право переставить все для повышения производительности. Хорошо, не все.CASE выражения имеют гарантированный порядок вычисления.

Решение довольно простое.Используйте NULLIF():

WHERE (Amount <> 0 AND Tax = 0) OR
      (Amount = 0 AND Tax <> 0) OR
      (Amount <> 0 AND Tax <> 0 AND ABS(Tax / NULLIF(Amount, 0) - 0.18) > 0.005)

WHERE Amount <> 0 AND Tax <> 0 AND ABS(Tax / NULLIF(Amount, 0) - 0.18) > 0.005
0 голосов
/ 04 октября 2018

пытались ли вы использовать круглые скобки

 SELECT InvoiceNumber, InvoiceDate, Amount, Tax
FROM Invoices
    WHERE (Amount <> 0 AND Tax = 0)
    OR (Amount = 0 AND Tax <> 0)
    OR (Amount <> 0 AND Tax <> 0 AND ABS(Tax / Amount - 0.18) > 0.005)

При работе с несколькими условиями (или / и) попробуйте затем разделить, используя "()".

Логический порядок операторов

  • Арифметика
  • Объединение
  • Условия сравнения
  • ЕСТЬ [НЕ] НЕДЕЙСТВИТЕЛЬНО, НРАВИТСЯ, [НЕ] IN
  • [НЕ] МЕЖДУ
  • Не равно
  • НЕ
  • И
  • ИЛИ

Вы можете использовать скобки для обработки этих правил.

...