Как правильно это сделать? Например, как мне изменить хранимую процедуру с этой подписью:
CREATE PROCEDURE dbo.MyProcedure
@Param BIT = NULL
AS
SELECT *
FROM dbo.SomeTable T
WHERE T.SomeColumn = @Param
Так что предоставление @Param значения 1 или 0 выполняет фильтр, но не указание его или передача NULL не выполняет фильтрацию?


Предполагая, что NULL означает «все равно», используйте
CREATE PROCEDURE dbo.MyProcedure
@Param BIT = NULL
AS
SELECT *
FROM dbo.SomeTable T
WHERE T.SomeColumn = @Param OR @Param IS NULL
Я думаю, что самый чистый способ сделать это (в T-SQL):
SELECT * FROM TABLE WHERE column = ISNULL(@param, column)
Другие СУБД предпочли бы COALESCE вместо ISNULL.
Я думаю, что более очевидно, в чем заключается цель, особенно когда вы начинаете добавлять другие предложения OR, а также избавляет вас от необходимости использовать парные скобки при объединении с предложениями AND.
В моем (очень) ограниченном тестировании также было незначительное увеличение производительности при использовании ISNULL по сравнению с OR @p IS NULL. Не то чтобы я выступал за использование ISNULL потому что для увеличения производительности (что в лучшем случае крайне незначительно, а в худшем - зависит от очень специфических случаев), но приятно знать, что это не требует значительных затрат. Честно говоря, я не уверен, почему это будет иметь значение в любом случае, но план выполнения показывает разницу в стоимости фильтра примерно на 1%.
Есть несколько способов. Вот один из них:
SELECT *
FROM dbo.SomeTable T
WHERE T.SomeColumn = COALESCE(@Param, T.SomeColumn)
но это не будет включать строки, для которых T.SomeColumn имеет значение NULL.
Следующая альтернатива будет включать эти строки:
SELECT *
FROM dbo.SomeTable T
WHERE T.SomeColumn = @Param OR @Param IS NULL
но у него есть недостаток в виде повторяющегося параметра, что нехорошо, если вы используете другой способ передачи параметров, например, с помощью заполнителя.