2009-05-01 5 views
27

У меня есть хранимая процедура в SQL Server 2000, которая выполняет поиск на основе значений параметров. Для одного из параметров, передаваемых в я нужен другой WHERE положение в зависимости от его стоимости - проблема заключается в том, что 3 значения не будет, где MyColumnWHERE IS NULL, NOT NULL или NO WHERE в зависимости от значения параметра SQL Server

  1. IS NULL
  2. IS NOT NULL
  3. ANY VALUE (NULL AND NOT NULL) (по существу не WHERE раздел)

У меня есть некоторый ментальный блок, который подходит к правильному синтаксису. Можно ли это сделать в одном заявлении выбора без выполнения какого-либо деления IF @parameter BEGIN ... END?

ответ

38

Вот как вы можете решить эту проблему с помощью одного WHERE пункта:

WHERE (@myParm = value1 AND MyColumn IS NULL) 
OR (@myParm = value2 AND MyColumn IS NOT NULL) 
OR (@myParm = value3) 

Наивного использование заявления СЛУЧАЯ не работает, под этим я имею в виду следующего:

SELECT Field1, Field2 FROM MyTable 
WHERE CASE @myParam 
    WHEN value1 THEN MyColumn IS NULL 
    WHEN value2 THEN MyColumn IS NOT NULL 
    WHEN value3 THEN TRUE 
END 

Это можно решить, используя делопроизводство, см. Onedaywhen's answer

+0

У вас была такая же идея, как у меня. Однако вам нужны скобки. – BobbyShaftoe

+0

Спасибо, Бобби, обновил мой ответ –

+1

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

-1

You shoul d взгляните на инструкцию CASE.

+0

Да, это еще один хороший метод. – BobbyShaftoe

+0

Я не верю, что вы можете использовать оператор CASE в этом сценарии, поскольку CASE оценивает одно выражение выражения –

+0

Это не так просто, как я думал, это было в этом случае. Вы можете добавить оператор case к предложению select, который делает то же самое, что и OR-ed вместе с предложением WHERE, но это просто даст вам менее читаемый оператор SQL. Я обновил свой ответ, чтобы показать это. –

12

Вы можете просто сделать что-то вроде этого:

SELECT * 
FROM foo 
WHERE (@param = 0 AND MyColumn IS NULL) 
OR (@param = 1 AND MyColumn IS NOT NULL) 
OR (@param = 2) 

Что-то вроде этого.

+0

Предположим, что мне нужно фильтровать строку. Если строка равна null, я должен вернуть все записи из таблицы, если она не является нулевой, я должен вернуть все записи, соответствующие строке или ее части (оператор LIKE). Как бы вы это решили? – Axel

9
WHERE MyColumn = COALESCE(@value,MyColumn) 
  • Если @value является NULL, он будет сравнивать MyColumn к себе, не обращая внимания @value = no where положение.

  • ЕСЛИ @value имеет значение (NOT NULL) будет сравнить MyColumn с @value.

Ссылка:COALESCE (Transact-SQL).

+0

Я не верю, что вы можете использовать оператор CASE в этом сценарии, поскольку CASE оценивает одно выражение. COALESCE или даже ISNULL Я не верю, что это сработает. –

+0

, пожалуйста, просмотрите мое редактирование, я полностью лишу что-то в вашем вопросе? –

+0

@Deviant - Я думаю, что ваш недостающий вопрос слегка. Предложение WHERE на MyColumn должно быть установлено другим значением, потому что оно напрямую не связано с значением параметра i.e, если NULL передан, тогда предложение WHERE отменяется. Если какое-либо другое значение передается, то набор результатов будет только для WHERE. MyColumn равен этому значению, а не MyColumn, имеющему известное значение. Предложение WHERE в MyColumn с NULLvalue не рассматривается. –

10

Вот как это можно сделать с помощью CASE:

DECLARE @myParam INT; 
SET @myParam = 1; 

SELECT * 
    FROM MyTable 
WHERE 'T' = CASE @myParam 
      WHEN 1 THEN 
       CASE WHEN MyColumn IS NULL THEN 'T' END 
      WHEN 2 THEN 
       CASE WHEN MyColumn IS NOT NULL THEN 'T' END 
      WHEN 3 THEN 'T' END; 
5

Другим способом СЛУЧАЙ:

SELECT * 
FROM MyTable 
WHERE 1 = CASE WHEN @myParm = value1 AND MyColumn IS NULL  THEN 1 
       WHEN @myParm = value2 AND MyColumn IS NOT NULL THEN 1 
       WHEN @myParm = value3       THEN 1 
      END 
+0

+1 решение. :) –

0

Я имел успех с этим решением. Это почти похоже на Патрика, с небольшим завихрением. Вы можете использовать эти выражения отдельно или последовательно. Если параметр пуст, он будет проигнорирован и все значения для столбца будут отображаться в вашем поиске, включая NULLS.

SELECT * FROM MyTable 
WHERE 
    --check to see if @param1 exists, if @param1 is blank, return all 
    --records excluding filters below 
(Col1 LIKE '%' + @param1 + '%' OR @param1 = '') 
AND 
    --where you want to search multiple columns using the same parameter 
    --enclose the first 'OR' expression in braces and enclose the entire 
    --expression 
((Col2 LIKE '%' + @searchString + '%' OR Col3 LIKE '%' + @searchString + '%') OR @searchString = '') 
AND 
    --if your search requires a date you could do the following 
(Cast(DateCol AS DATE) BETWEEN CAST(@dateParam AS Date) AND CAST(GETDATE() AS DATE) OR @dateParam = '') 
Смежные вопросы