WHERE是NULL,IS NOT NULL或NO WHERE子句取决于SQL Server参数值

时间:2009-05-01 09:02:10

标签: sql sql-server sql-server-2000

我在SQL Server 2000中有一个存储过程,它根据参数值执行搜索。对于传入的其中一个参数,我需要一个不同的WHERE子句,具体取决于它的值 - 问题是3个值将在MyColumn

的位置
  1. IS NULL
  2. IS NOT NULL
  3. ANY VALUE (NULL AND NOT NULL)(基本上没有WHERE条款)
  4. 我在提出正确的语法方面遇到了一些心理障碍。这可以在一个选择语句中执行而不执行某些IF @parameter BEGIN ... END分支吗?

7 个答案:

答案 0 :(得分:41)

以下是使用单个WHERE子句解决此问题的方法:

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

CASE声明的天真用法不起作用,我的意思是:

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

可以使用case语句来解决这个问题,请参阅onedaywhen的answer

答案 1 :(得分:13)

你可以这样做:

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

类似的东西。

答案 2 :(得分:10)

WHERE MyColumn = COALESCE(@value,MyColumn) 
  • 如果@valueNULL,则会将MyColumn与自身进行比较,忽略 @value = no where条款。

  • 如果@value的值为NOT NULL,则会将MyColumn@value进行比较 {{1}}。

参考: COALESCE (Transact-SQL)

答案 3 :(得分: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;

答案 4 :(得分:5)

CASE的另一种方式:

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

答案 5 :(得分: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 = '')

答案 6 :(得分:0)

可以使用EXISTS实现这种逻辑:

CREATE TABLE tab(a INT, b VARCHAR(10));
INSERT INTO tab(a,b) VALUES(1,'a'),(1, NULL),(NULL, 'a'),(2,'b');

查询:

DECLARE @a INT;

--SET @a = 1;    -- specific NOT NULL value
--SET @a = NULL; -- NULL value
--SET @a = -1;   -- all values

SELECT *
FROM tab t
WHERE EXISTS(SELECT t.a INTERSECT SELECT @a UNION SELECT @a WHERE @a = '-1');

db<>fiddle demo

它可以扩展为包含多个参数:

SELECT *
FROM tab t
WHERE EXISTS(SELECT t.a INTERSECT SELECT @a UNION SELECT @a WHERE @a = '-1')
  AND EXISTS(SELECT t.b INTERSECT SELECT @b UNION SELECT @a WHERE @b = '-1');