#sql #stored-procedures
Вопрос:
Как правильно это сделать? Например, как бы я изменил хранимую процедуру с помощью этой подписи:
CREATE PROCEDURE dbo.MyProcedure
@Param BIT = NULL
AS
SELECT *
FROM dbo.SomeTable T
WHERE T.SomeColumn = @Param
Таким образом, предоставление @Param со значением 1 или 0 выполняет фильтр, но его указание или передача значения NULL не выполняет фильтрацию?
Ответ №1:
Предполагая, что NULL означает «все равно», затем используйте
CREATE PROCEDURE dbo.MyProcedure
@Param BIT = NULL
AS
SELECT *
FROM dbo.SomeTable T
WHERE T.SomeColumn = @Param OR @Param IS NULL
Ответ №2:
Есть более чем один способ. Вот один из них:
SELECT *
FROM dbo.SomeTable T
WHERE T.SomeColumn = COALESCE(@Param, T.SomeColumn)
но это не будет включать строки, для которых T. SomeColumn равен НУЛЮ.
Следующая альтернатива будет включать эти строки:
SELECT *
FROM dbo.SomeTable T
WHERE T.SomeColumn = @Param OR @Param IS NULL
но у него есть недостаток в повторном параметре, что нехорошо, если вы используете другой способ передачи параметров, например, с помощью заполнителя.
Ответ №3:
Мне кажется, что самый чистый способ сделать это (в T-SQL) — это:
SELECT * FROM TABLE WHERE column = ISNULL(@param, column)
Другие СУБД предпочли бы ОБЪЕДИНЯТЬСЯ вместо ISNULL.
Я думаю, что здесь более очевидно, в чем заключается цель, особенно когда вы начинаете добавлять другие предложения ИЛИ, и это также избавляет вас от необходимости в родителях при объединении с предложениями И.
В моем (очень) ограниченном тестировании также наблюдалось незначительное увеличение производительности при использовании ISNULL по сравнению с ИЛИ @p РАВНО НУЛЮ. Не то чтобы я выступаю за использование ISNULL из-за увеличения производительности (что в лучшем случае крайне незначительно и в худшем случае зависит от очень конкретных случаев), но приятно знать, что это не имеет значительных затрат. Честно говоря, я не уверен, почему это так или иначе изменило бы ситуацию, но план выполнения показывает разницу в стоимости фильтра примерно на 1%.