Использование параметра с тремя состояниями в хранимой процедуре

Как правильно это сделать? Например, как мне изменить хранимую процедуру с этой подписью:

CREATE PROCEDURE dbo.MyProcedure
  @Param BIT = NULL
AS
  SELECT *
  FROM dbo.SomeTable T
  WHERE T.SomeColumn = @Param

Так что предоставление @Param значения 1 или 0 выполняет фильтр, но не указание его или передача NULL не выполняет фильтрацию?

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
0
711
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Предполагая, что 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

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

Другие вопросы по теме