SQL Server 2005 - предложение WHERE - использовать IF или CASE или BOOLEAN? - PullRequest
2 голосов
/ 02 ноября 2010

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

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

Я пытаюсь создать один запрос для этого.

Вот мой псевдокод (SQL Server 2005):

declare @a varchar(10); set @a = null;
declare @b varchar(10); set @b = 'comm%';

select * from x
where (if @a is not null then col1 like @a)
and (if @b is not null then col2 like @b)

Как видите, я хочу фильтровать только по col1 , если мой параметр (@a) содержит данные.Точно так же я хочу фильтровать только col2 , если в моем параметре (@b) есть данные.Если @a и @b равны NULL, то запрос должен вернуть все строки.

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

Ответы [ 3 ]

4 голосов
/ 02 ноября 2010

Вы были близки - используйте:

SELECT x.*
  FROM X x
 WHERE (@a IS NULL OR x.col1 LIKE @a)
   AND (@b IS NULL OR x.col2 LIKE @b)

Но это не рекомендуется, потому что это не может быть sargable . Динамический SQL будет лучшим подходом:

DECLARE @SQL NVARCHAR(MAX)
    SET @SQL = N'SELECT x.*
                   FROM X x
                  WHERE 1 = 1 '

    SET @SQL = @SQL + CASE
                        WHEN @a IS NULL THEN ' ' 
                        ELSE ' AND x.col1 LIKE @a '
                      END 

    SET @SQL = @SQL + CASE
                        WHEN @b IS NULL THEN ' ' 
                        ELSE ' AND x.col2 LIKE @b '
                      END 

BEGIN

  EXEC sp_executesql @SQL, 
                     N'@a VARCHAR(10), @b VARCHAR(10)',
                     @a, @b

END
2 голосов
/ 02 ноября 2010
SELECT * FROM X WHERE (@a IS NULL OR col1 LIKE @a) AND (@b IS NULL OR col2 LIKE @b)
1 голос
/ 02 ноября 2010

Вероятно, это будет самый эффективный способ сделать то, что вы ищете. Фильтрация будет выполняться только для столбца, если значение, переданное хранимой процедуре, не равно NULL:

CREATE PROCEDURE sproc_example
@Col1 varchar(30) = NULL,
@Col2 varchar(30) = NULL,
@Col3 varchar(30) = NULL
AS
SELECT Col1,
       Col2,
       Col3
FROM MyTable
WHERE Col1 LIKE COALESCE(@Col1,Col1) AND
      Col2 LIKE COALESCE(@Col2,Col2) AND
      Col3 LIKE COALESCE(@Col3,Col3)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...