Почему я не могу использовать оператор if внутри оператора select? Кто-нибудь знает другой метод? - PullRequest
3 голосов
/ 12 августа 2011
Select b.ItemKey, a.CatKey, a.ParentKey, a.CatName, g.ItemID, c.UserFld1, c.UserFld3, c.UserFld5, f.UOMID, e.SizeValue
From dbo.timWebCategory a Inner JOIN
    dbo.timWebCategoryItem b ON a.CatKey = b.CatKey Inner JOIN
    mas500_app.dbo.timItem c ON b.ItemKey = c.ItemKey Inner JOIN
    dbo.cpsIMItemDetails d ON c.ItemKey = d.ItemKey Inner JOIN
    dbo.timItemSize e ON c.ItemKey = e.ItemKey Left JOIN
    dbo.timVolumeUOM f ON e.VolUOMKey = f.VolUOMKey Left JOIN
    mas500_app.dbo.vWebItem g ON c.ItemKey = g.ItemKey
Where a.Catkey = @Key
AND d.IntFlg = 1
If @color is not Null 
Begin
    AND c.UserFld1 = @color
End
Order By f.UOMID, e.SizeValue**

Возвращает это: Неверный синтаксис рядом с ключевым словом «И».

Ответы [ 3 ]

1 голос
/ 12 августа 2011

Попробуйте это ...

Select b.ItemKey, a.CatKey, a.ParentKey, a.CatName, g.ItemID, c.UserFld1, c.UserFld3, c.UserFld5, f.UOMID, e.SizeValue
From dbo.timWebCategory a Inner JOIN
    dbo.timWebCategoryItem b ON a.CatKey = b.CatKey Inner JOIN
    mas500_app.dbo.timItem c ON b.ItemKey = c.ItemKey Inner JOIN
    dbo.cpsIMItemDetails d ON c.ItemKey = d.ItemKey Inner JOIN
    dbo.timItemSize e ON c.ItemKey = e.ItemKey Left JOIN
    dbo.timVolumeUOM f ON e.VolUOMKey = f.VolUOMKey Left JOIN
    mas500_app.dbo.vWebItem g ON c.ItemKey = g.ItemKey
Where a.Catkey = @Key
AND d.IntFlg = 1
AND (@color = c.UserFld1 OR @color is null)
Order By f.UOMID, e.SizeValue**
0 голосов
/ 12 августа 2011

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

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

Есть разные способы справиться с этим, например, с помощью функции isnull для сравнения значения с самим собой, если varaible имеет значение null:

AND c.UserFld1 = isnull(@color, c.UserFld1)

Или проверка на ноль перед сравнением:

AND (@coor is null or c.UserFld1 = @color)

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

If @color is not Null Begin

  Select b.ItemKey, a.CatKey, a.ParentKey, a.CatName, g.ItemID, c.UserFld1, c.UserFld3, c.UserFld5, f.UOMID, e.SizeValue
  From dbo.timWebCategory a Inner JOIN
    dbo.timWebCategoryItem b ON a.CatKey = b.CatKey Inner JOIN
    mas500_app.dbo.timItem c ON b.ItemKey = c.ItemKey Inner JOIN
    dbo.cpsIMItemDetails d ON c.ItemKey = d.ItemKey Inner JOIN
    dbo.timItemSize e ON c.ItemKey = e.ItemKey Left JOIN
    dbo.timVolumeUOM f ON e.VolUOMKey = f.VolUOMKey Left JOIN
    mas500_app.dbo.vWebItem g ON c.ItemKey = g.ItemKey
  Where a.Catkey = @Key
    AND d.IntFlg = 1
    AND c.UserFld1 = @color
  Order By f.UOMID, e.SizeValue

End Else Begin

  Select b.ItemKey, a.CatKey, a.ParentKey, a.CatName, g.ItemID, c.UserFld1, c.UserFld3, c.UserFld5, f.UOMID, e.SizeValue
  From dbo.timWebCategory a Inner JOIN
    dbo.timWebCategoryItem b ON a.CatKey = b.CatKey Inner JOIN
    mas500_app.dbo.timItem c ON b.ItemKey = c.ItemKey Inner JOIN
    dbo.cpsIMItemDetails d ON c.ItemKey = d.ItemKey Inner JOIN
    dbo.timItemSize e ON c.ItemKey = e.ItemKey Left JOIN
    dbo.timVolumeUOM f ON e.VolUOMKey = f.VolUOMKey Left JOIN
    mas500_app.dbo.vWebItem g ON c.ItemKey = g.ItemKey
  Where a.Catkey = @Key
    AND d.IntFlg = 1
  Order By f.UOMID, e.SizeValue

End
0 голосов
/ 12 августа 2011

Переверните это "наизнанку". Вы не можете условно вставить AND, вы всегда должны сказать AND, и затем вы можете использовать if-else (или просто OR, как и другой ответ), чтобы условно предоставить либо условие, которое вы хотите, либо просто true / false.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...