Microsoft SQL: СЛУЧАЙ, КОГДА ПРОТИВ ISNULL / NULLIF - PullRequest
4 голосов
/ 13 мая 2009

Кроме читабельности, есть ли существенная польза от использования оператора CASE WHEN против ISNULL / NULLIF при защите от ошибки деления на 0 в SQL?

CASE WHEN (BeginningQuantity + BAdjustedQuantity)=0 THEN 0 
ELSE EndingQuantity/(BeginningQuantity + BAdjustedQuantity) END

против

ISNULL((EndingQuantity)/NULLIF(BeginningQuantity + BAdjustedQuantity,0),0)

Ответы [ 6 ]

7 голосов
/ 13 мая 2009

Помните, что NULL отличается от 0. Поэтому два фрагмента кода в вопросе могут возвращать разные результаты для одного и того же ввода.

Например, если BeginningQuantity имеет значение NULL, первое выражение оценивается как NULL:

CASE WHEN (NULL + ?)=0 THEN 0 ELSE ?/(NULL + ?) END

Теперь (NULL +?) Равно NULL, а NULL = 0 - false, поэтому предложение ELSE оценивается, давая? / (NULL +?), Что приводит к NULL. Тем не менее, второе выражение становится:

ISNULL((?)/NULLIF(NULL + ?,0),0)

Здесь NULL +? становится NULL, и поскольку NULL не равен 0, NULLIF возвращает первое выражение, которое является NULL. Внешний ISNULL ловит это и возвращает 0.

Итак, примите решение: вы защищаете от деления на ноль или деления на NULL? ; -)

3 голосов
/ 13 мая 2009

В вашем примере я думаю, что производительность незначительна. Но в других случаях, в зависимости от сложности вашего делителя, ответ «это зависит».

Вот интересный блог на тему:

Для удобства чтения мне нравится Case / When.

0 голосов
/ 03 ноября 2009

Извините, вот еще более упрощенный упрощенный SQL-запрос.

SELECT 

(ISNULL([k1],0) + ISNULL([k2],0)) /

CASE WHEN (
(
   CASE WHEN [k1] IS NOT NULL THEN 1 ELSE 0 END +
   CASE WHEN [k2] IS NOT NULL THEN 1 ELSE 0 END
) > 0 )
THEN
(
  CASE WHEN [k1] IS NOT NULL THEN 1 ELSE 0 END +
  CASE WHEN [k2] IS NOT NULL THEN 1 ELSE 0 END
)
ELSE 1 END

FROM dbo.[Table]
0 голосов
/ 13 мая 2009
CASE WHEN (coalesce(BeginningQuantity,0) + coalesce(BAdjustedQuantity,0))=0 THEN 0 ELSE coalesce(EndingQuantity,0)/(coalesce(BeginningQuantity,0) + coalesce(BAdjustedQuantity,0)) END

ваш лучший вариант imho

0 голосов
/ 13 мая 2009

Я бы использовал ISNULL, но попробуйте отформатировать его так, чтобы он лучше отображал значение:

SELECT
    x.zzz
        ,x.yyyy
        ,ISNULL(
                   EndingQuantity / NULLIF(BeginningQuantity+BAdjustedQuantity,0)
                ,0)
        ,x.aaa
    FROM xxxx...
0 голосов
/ 13 мая 2009

По моему мнению, использование Isnull / Nullif быстрее, чем использование Case When. Я, скорее, isnull / nullif.

...