Sql WHERE子句中的可选参数

Sql WHERE子句中的可选参数,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,假设有一个具有3个参数的存储过程。在所有可能的情况下,我希望通过一个WHERE子句来实现这一点,而不会因为使用()和()或()太多而失控 例如: //Params @CITY VARCHAR(100) = NULL, @GENDER VARCHAR(100) = NULL, @AGE VARCHAR(100) = NULL 我想你可以用如果开始。。。如果存在每个变量,则结束,但这会使代码比预期长很多 下面这个方法不起作用,因为它太长了(像这样有10个不同的字段,但示例只有3个),而且我

假设有一个具有3个参数的存储过程。在所有可能的情况下,我希望通过一个
WHERE
子句来实现这一点,而不会因为使用
()和()或()
太多而失控

例如:

    //Params
@CITY VARCHAR(100) = NULL,
@GENDER VARCHAR(100) = NULL,
@AGE VARCHAR(100) = NULL
我想你可以用
如果开始。。。如果存在每个变量,则结束
,但这会使代码比预期长很多

下面这个方法不起作用,因为它太长了(像这样有10个不同的字段,但示例只有3个),而且我不确定它是否直接提取不同的值

SELECT NAME FROM TABLE 
WHERE (
(CITY=@CITY AND GENDER=@GENDER AND AGE=@AGE)
OR (CITY=@CITY AND GENDER=@GENDER)
OR (GENDER=@GENDER AND AGE=@AGE)
OR (CITY=@CITY AND AGE=@AGE)
OR (CITY=@CITY)
OR (GENDER=@GENDER)
OR (AGE=@AGE)
)
有没有更快捷、更有效的方法

如果是,则该方法最好也与JOIN兼容。

可能是:

create procedure myProc
    --Params
@CITY VARCHAR(100) = NULL,
@GENDER VARCHAR(100) = NULL,
@AGE VARCHAR(100) = NULL
as

SELECT NAME FROM [TABLE]
WHERE ISNULL(CITY,'')=ISNULL(@CITY,ISNULL(CITY,''))
AND ISNULL(GENDER,'')=ISNULL(@GENDER,ISNULL(GENDER,''))
AND ISNULL(AGE,'')=ISNULL(@AGE,ISNULL(AGE,''))
go

假设WHERE子句中的列可以为null,使用ISNULL可避免null比较。

尝试以下操作:

SELECT NAME 
FROM TABLE 
WHERE 
    City = IsNull(@City, City) AND
    Gender = IsNull(@Gender, Gender) AND
    Age = IsNull(@Age, Age)
或:

这个怎么样

SELECT
    NAME
FROM TABLE 
WHERE CITY = COALESCE(@CITY, CITY)
    AND GENDER = COALESCE(@GENDER, GENDER)
    AND AGE = COALESCE(@AGE, AGE)

除了
ISNULL
/
COALESCE
选项之外,您还可以测试参数是否为null:

SELECT NAME  
FROM TABLE  
WHERE  
    (@City IS NULL OR City = @City)
AND 
    (@Gender IS NULL OR Gender = @Gender)
AND 
    (@Age IS NULL OR Age = @Age) 

旁注:当定义
VARCHAR()
-作为存储过程的参数或局部变量时,应始终定义长度!否则,您可能会无意中得到
VARCHAR(1)
字符串…可选字段意味着如果没有或
NULL
值,则不在Where子句中显示,是否可能?请阅读以下内容:uggghhh。。我想避免那样做。。类似于“IsNull”的东西吗?我想你的第一个例子可能会删掉它,让我来看看。。brb.关于第一个选项……NULL是否等于NULL?
Select*From Table Where NULL为NULL
将返回所有行。在本上下文中,这是可以的,因为这意味着如果您向参数传递一个
NULL
值,则不希望通过该参数进行筛选。是,但从表中选择*时,其中NULL=NULL将不包括具有NULL列值的行。在具有包含null的可空列的表上进行测试。e、 g:从mytable中选择*其中mycolumn=IsNull(null,mycolumn)City=IsNull(@City,City)格式我以前从未遇到过。外观漂亮整洁。我知道现在发表评论有点太晚了,但请小心使用这种方法,因为SQL Server不能保证评估的顺序(它肯定不会短路)。因此,您最好让SQL Server完成所有不必要的检查。@IlyaChernomordik:并刷新性能。@IlyaChernomordik那么,有什么更好的方法可以做到这一点呢?想到了动态sql,但它会带来其他问题,如维护、代码清除等。没有其他更好的方法了?至少我不知道:)如果动态sql变得足够复杂并开始影响性能,我会使用动态sql。动态sql查询会导致性能下降,似乎最好的办法是使用if..ELSE或Case语句,我想通过这种方式,两个执行计划将被制定,并将被缓存,我有这样一个问题,请看一下它开始。美丽的!如果遇到空变量,SQL Server有望优化这些条件。测试起来会很有趣。这很好,但是如果说,
CITY
@CITY
都为null,则不会包含记录,因为null不等于null(除非
ANSI_NULLS
设置为OFF)。我怀疑CITY=CITY条件和Column=Column条件是否无效,例如,null=null可能会导致未知,而另一方面,如果我们的列不为null,那么我们将得到column=column条件的完整扫描表。
SELECT NAME  
FROM TABLE  
WHERE  
    (@City IS NULL OR City = @City)
AND 
    (@Gender IS NULL OR Gender = @Gender)
AND 
    (@Age IS NULL OR Age = @Age) 
SELECT NAME   
FROM TABLE   
WHERE       
  City = case when isnull(@City ,'') = '' then City
                        else @City end
AND      
  Gender = case when isnull(@Gender ,'') = '' then Gender
                        else @Gender end
AND  
  Age = case when isnull(@Age ,0) = 0 then Age
                        else @Age end