Параметр бита хранимой процедуры, активирующий дополнительное условие where для проверки на нулевое значение - PullRequest
4 голосов
/ 30 сентября 2008

У меня есть хранимая процедура, которая выглядит следующим образом:

CREATE PROCEDURE dbo.usp_TestFilter
  @AdditionalFilter BIT = 1
AS
  SELECT *
  FROM dbo.SomeTable T
  WHERE
    T.Column1 IS NOT NULL
    AND CASE WHEN @AdditionalFilter = 1 THEN
      T.Column2 IS NOT NULL

Излишне говорить, что это не работает. Как я могу активировать дополнительное условие where, которое проверяет параметр @AdditionalFilter? Спасибо за любую помощь.

Ответы [ 4 ]

6 голосов
/ 30 сентября 2008
CREATE PROCEDURE dbo.usp_TestFilter
  @AdditionalFilter BIT = 1
AS
  SELECT *
  FROM dbo.SomeTable T
  WHERE
    T.Column1 IS NOT NULL
    AND (@AdditionalFilter = 0 OR
      T.Column2 IS NOT NULL)

Если @AdditionalFilter равен 0, столбец не будет оцениваться, поскольку он не может повлиять на результат выполнения части в скобках. Если значение равно 0, условие столбца будет оценено.

4 голосов
/ 30 сентября 2008

Эта практика приводит к путанице в оптимизаторе запросов. Я видел, как SQL Server 2000 строил план выполнения с точностью до наоборот и использовал индекс для Column1, когда был установлен флаг, и наоборот. Казалось, что SQL Server 2005, по крайней мере, правильно разработал план выполнения при первой компиляции, но у вас возникла новая проблема. Система кэширует скомпилированные планы выполнения и пытается использовать их повторно. Если вы сначала используете запрос одним способом, он все равно выполнит запрос таким образом, даже если изменится дополнительный параметр, и более подходящими будут другие индексы.

Вы можете принудительно перекомпилировать хранимую процедуру при выполнении, используя WITH RECOMPILE в операторе EXEC или каждый раз, указав WITH RECOMPILE в операторе CREATE PROCEDURE. За повторный анализ и оптимизацию запроса SQL Server будет налагаться штраф.

Как правило, если форма вашего запроса изменится, используйте динамическую генерацию SQL с параметрами . SQL Server также будет кэшировать планы выполнения для параметризованных и автоматически параметризованных запросов (где он пытается определить, какие аргументы являются параметрами) и даже для обычных запросов, но он придает больше значения планам выполнения хранимых процедур, затем параметризованным, автоматически параметризованным регулярные запросы в этом порядке. Чем больше вес, тем дольше он может оставаться в оперативной памяти до того, как план будет удален, если серверу понадобится память для чего-то другого.

1 голос
/ 30 сентября 2008
CREATE PROCEDURE dbo.usp_TestFilter
  @AdditionalFilter BIT = 1
AS
  SELECT *
  FROM dbo.SomeTable T
  WHERE
    T.Column1 IS NOT NULL
    AND (NOT @AdditionalFilter OR T.Column2 IS NOT NULL)
0 голосов
/ 30 сентября 2008
select *
from SomeTable t
where t.Column1 is null
and (@AdditionalFilter = 0 or t.Column2 is not null)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...