2010-07-18 77 views
4

环境Select语句:SQL Server 2005中的SQL Server 2005:在ISNULL条件

我有收到逗号,一个参数的值分开存储的过程。我在SQL中编写了一个Table Value UDF函数来打破它,并将它作为表返回给我。我正在使用该值来过滤存储过程的where子句中的数据。一切正常,直到在传递给存储过程的逗号分隔变量中有NULL。我想以这样的方式编写我的where子句,如果传递的变量是NULL,那么它不应该使用Split函数。这是我在存储过程中所做的。

Declare @list varchar(100), @Col2 varchar(100) 

SELECT * 
    FROM Table1 t1 
INNER JOIN dbo.Table2 t2 ON t1.Col1 = t2.Col1 
WHERE t1.Col2 = ISNULL(@Col2,t1.Col2) 
--I want to write below condition the same way i have written the above condition 
    AND t1.Col3 IN (select * from dbo.SplitMe(@list)) 

有没有办法编写条件来选择Col3选择Col2的方式?

回答

2

如果这个想法是不是Col3如果@list是空滤,那么你可能用同样的方式

Declare @list varchar(100), @Col2 varchar(100) 

SELECT * 
    FROM Table1 t1 
INNER JOIN dbo.Table2 t2 
on t1.Col1 = t2.Col1 

where t1.Col2 = ISNULL(@Col2,t1.Col2) 
AND (@list IS NULL OR t1.Col3 IN (select * from dbo.SplitMe(@list))) 

,但它不会是一个好主意,除非这些表是非常小的。对于计划缓存的原因,通常最好将所有这些排列闯入自己的SQL语句,而不是试图写一个一刀切的查询或者(如果置换的数量变得太大)考虑使用动态SQL(见Dynamic Search Conditions in T-SQL

注意这保证Split函数将不会被调用。没有保证条款评估的顺序。但是这意味着如果它被调用,它将不会影响查询的结果。 (编辑假设当然是被调用时NULL实际上并没有造成某种错误C.F. Remus的评论)

+1

依赖布尔运算符在SQL中短路是非常危险的,因为它是**不**保证:http://rusanu.com/2009/09/13/on-sql-server-boolean- operator-short-circuit/ – 2010-07-18 17:37:19

+0

这就是我一直在寻找的东西。非常感谢。截至目前,我将与此同时进行,但如果性能会下降,我会将其更改为动态查询以查看是否有所改进。 – Asdfg 2010-07-21 07:38:37

1

您有现在的两个变量是相互独立的查询。在一个查询中包括它们两个会产生一个非可查询的查询 - 根据变量值查询会有很大的不同,并且您使用的是昂贵的条件表达式来将它们放在一起。这是一个痛苦的维护,并表现不佳。

你可以使用IF语句:

IF 
BEGIN 

    SELECT * 
     FROM TABLE1 t1 
     JOIN TABLE2 t2 ON t2.col1 = t1.col1 
    WHERE t1.col1 = COALESCE(@col2, t1.col2) 

END 
ELSE 
BEGIN 

    SELECT * 
     FROM TABLE1 t1 
     JOIN TABLE2 t2 ON t2.col1 = t1.col1 
     WHERE t1.col2 = COALESCE(@col2, t1.col2) 
      AND t1.col3 IN (SELECT * FROM dbo.splitme(@list)) 

END 

...但仍有空处理。对于两个变量,这是四种可能的价值结果。像这样的情况是动态SQL的意图 - 构建查询是必要的,因为拖拉行李运行不佳。

+0

我知道这是一个很好的动态SQL候选人,但我更喜欢编写干净的SQL。另外参数的数量不限于2,所以我不认为为每个排列和组合编写SQL都是一个好主意。纠正我,如果我错了。 – Asdfg 2010-07-21 07:35:59

+0

@Asdfg:当你有两个或更多个参数,可能的组合增加了通过平方的参数#:2变为4点的可能性,3装置9等更多的可能性,越有可能的查询高速缓存将无益处提供小在非动态的方法。这不仅是嵌入到SQL中的OR和其他条件逻辑的影响。动态SQL *是*干净的SQL - 它只是实际需要运行的内容,而不是处理各种情况的所有行李。参数越多,动态SQL的执行效果就会比您选择的答案更好。 – 2010-07-21 15:53:36

1
WHERE (t1.Col2 = @Col2 OR @Col2 IS NULL) 
AND (t1.Col3 IN (select * from dbo.SplitMe(@list)) OR @list IS NULL)