Если вы пишете код так:
SELECT * FROM products
WHERE price > 100
AND (total_sales / price) > 10;
Можно предположить, что запрос будет вычисляться слева направо, и это предотвратит ошибку деления на ноль. Однако это не всегда так. Большинство крупных SQL-баз данных НЕ гарантируют short-circuit-вычисление условий AND в WHERE. И даже если в простых случаях кажется, что short-circuit работает, оптимизатор часто перестраивает или вычисляет выражения вне исходного порядка по соображениям производительности.
Это означает, что база данных может попытаться вычислить:
total_sales / priceраньше, чем:
price > 100.То есть, если какое-либо значение в
price равно нулю, может возникнуть ошибка деления на ноль.Таким образом, даже несмотря на то, что логически условие
price > 100 должно предотвращать деление на ноль, фактический порядок выполнения не гарантирует этого.Чтобы обезопасить себя, можно использовать оператор
NULLIF в WHERE:SELECT *
FROM products
WHERE price > 100
AND (total_sales / NULLIF(price, 0)) > 10;
Никогда не используйте деление в
WHERE, если знаменатель не защищён через NULLIF(), не переписан в умноженную форму (например, numerator > denominator * constant) или не обёрнут в CASE.👉 @SQLPortal
