Sql WHERE子句中的可选参数
假设有一个具有3个参数的存储过程。在所有可能的情况下,我希望通过一个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个),而且我
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