Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server 2005:处于ISNULL条件的Select语句_Sql_Sql Server_Sql Server 2005_Tsql - Fatal编程技术网

SQL Server 2005:处于ISNULL条件的Select语句

SQL Server 2005:处于ISNULL条件的Select语句,sql,sql-server,sql-server-2005,tsql,Sql,Sql Server,Sql Server 2005,Tsql,环境:SQLServer2005 我有一个存储过程,它在一个参数中接收逗号分隔的值。我已经在SQL中编写了一个表值UDF函数来分解它并将其作为表返回给我。我正在使用该值过滤存储过程where子句中的数据。在传递给存储过程的逗号分隔变量中出现NULL之前,一切都正常。我希望以这样一种方式编写where子句:如果传递的变量为NULL,那么它就不应该使用Split函数。下面是我在存储过程中所做的操作 Declare @list varchar(100), @Col2 varchar(100) SEL

环境:SQLServer2005

我有一个存储过程,它在一个参数中接收逗号分隔的值。我已经在SQL中编写了一个表值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))

有没有一种方法可以像选择Col2那样写入选择Col3的条件?

如果想法是不按
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(参见)


注意,这并不保证Split函数不会被调用。没有保证条款的评估顺序。但这确实意味着,如果它真的被调用,它将不会对查询结果产生任何影响。(Edit当然,假设在
NULL
时被调用实际上不会导致某种错误c.f.Remus的评论)

您现在有一个查询,其中有两个相互独立的变量。在一个查询中同时包含这两个变量会产生一个不可搜索的查询-根据变量值的不同,查询会有很大的不同,并且您需要使用昂贵的条件表达式将其保持在一起。这不仅是一个痛苦的维持,而且表现不佳

您可以使用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的用意——构造必要的查询,因为拖拉行李的性能不好

在SQL中依赖布尔运算符短路是非常危险的,因为它不能保证:这就是我要找的。谢谢。到目前为止,我将继续使用这个方法,但是如果性能很差,我将把它改为动态查询,看看它是否有所改进。我知道这是动态SQL的一个很好的候选方法,但我更喜欢编写干净的SQL。而且参数的数量不限于2,所以我不认为为每个排列和组合编写SQL是一个好主意。如果我错了,请纠正我。@Asdfg:当您有两个或更多参数时,可能的组合会通过对参数的平方增加:2变为4种可能性,3表示9,等等。可能性越大,查询缓存在非动态方法中提供的好处就越少甚至没有。除了OR和嵌入SQL的其他条件逻辑的影响之外。动态SQL是干净的SQL—它只是实际需要运行的内容,而不是处理各种情况的全部负担。参数越多,与您选择的答案相比,动态SQL的性能就越好。
WHERE (t1.Col2 = @Col2 OR @Col2 IS NULL)
AND (t1.Col3 IN (select * from dbo.SplitMe(@list)) OR @list IS NULL)