WHERE为NULL、NOT NULL或NO WHERE子句,具体取决于SQL Server参数值
我在SQLServer2000中有一个存储过程,它根据参数值执行搜索。对于传入的其中一个参数,我需要一个不同的WHERE为NULL、NOT NULL或NO WHERE子句,具体取决于SQL Server参数值,sql,sql-server,sql-server-2000,Sql,Sql Server,Sql Server 2000,我在SQLServer2000中有一个存储过程,它根据参数值执行搜索。对于传入的其中一个参数,我需要一个不同的WHERE子句,具体取决于它的值-问题是这3个值将位于WHEREMyColumn 为空 不为空 任何值(NULL和NOTNULL)(本质上是no,其中子句) 我在想出正确的语法时遇到了一些心理障碍。如果@parameter BEGIN。。。结束分支?以下是如何使用单个WHERE子句解决此问题: WHERE (@myParm = value1 AND MyColumn IS NULL) O
WHERE
子句,具体取决于它的值-问题是这3个值将位于WHEREMyColumn
为空
不为空
任何值(NULL和NOTNULL)
(本质上是no,其中
子句)我在想出正确的语法时遇到了一些心理障碍。如果@parameter BEGIN。。。结束分支?以下是如何使用单个
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
可以使用case语句解决此问题,请参见onedaywhen的您可以这样做:
SELECT *
FROM foo
WHERE (@param = 0 AND MyColumn IS NULL)
OR (@param = 1 AND MyColumn IS NOT NULL)
OR (@param = 2)
差不多吧
WHERE MyColumn = COALESCE(@value,MyColumn)
- 如果
为@value
,它会将NULL
与自身进行比较,忽略MyColumn
子句@value=no where
- 如果
有一个值(@value
),它将把非NULL
与MyColumn
@value
参考:这是如何使用
案例来完成的:
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;
另一种情况是:
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
我已经成功地解决了这个问题。它几乎像帕特里克的,有点扭曲。您可以单独或按顺序使用这些表达式。如果参数为空,将忽略该参数,并显示搜索列的所有值,包括空值
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 = '')
这种逻辑可以使用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');
它可以扩展为包含多个参数:
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');
你的想法和我一样。但是,您确实需要括号,我不确定您是否需要括号,但我非常支持复杂布尔表达式中的括号。如果你问我的话,没有它们会让编译器来执行操作顺序,这是相当可怕的。我已经尝试了CASE语句,但是CASE的计算结果是一个结果表达式,因此计算“is NULL”、“is Not NULL”、“myColumn is NULL”等都不起作用。现在我正在测试你的第一个答案,我也试过了,但案例并没有这样起作用。因此,我建议使用案例陈述来解决这个问题(见我的答案)是错误的。我没有想过这样做。现在我需要去修复一些存储过程。。。谢谢,我不相信您可以在这个场景中使用CASE语句,因为CASE的计算结果是一个结果表达式。COALESCE或甚至ISNULL我也不相信会起作用。请查看我的编辑,我是否完全遗漏了您问题中的某些内容?@Deviant-我认为您稍微遗漏了问题。MyColumn上的WHERE子句需要由另一个值设置,因为它与参数值没有直接关系,即如果传递NULL,则WHERE子句将被否定。如果传递了任何其他值,那么结果集将仅用于MyColumn等于该值的位置,而不是具有已知值的MyColumn。MyColumn的WHERE子句有一个空值,这是使用COALESCE的工作原理,我不必说我需要用字符串过滤。如果字符串为null,我应该返回表中的所有记录,如果它不是null,我应该返回与字符串或其一部分匹配的所有记录(如运算符)。你将如何解决这个问题?假设我需要通过字符串进行过滤。如果字符串为null,我应该返回表中的所有记录,如果它不是null,我应该返回与字符串或其一部分匹配的所有记录(如运算符)。你将如何解决这个问题?