环境:SQL Server 2005
我有一个存储过程,它在一个参数中接收逗号分隔值。我在SQL中编写了一个Table Valued 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的条件?
答案 0 :(得分: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(请参阅{{3} })
请注意,此不保证不会调用Split函数。没有保证的条款评估顺序。但它确实意味着如果它被调用它将对查询的结果没有影响。 (编辑当然假设当NULL
实际上不会导致某种错误时被调用c.f. Remus的评论)
答案 1 :(得分: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的意图 - 构建必要的查询,因为拖拽行李不能很好地执行。
答案 2 :(得分:1)
WHERE (t1.Col2 = @Col2 OR @Col2 IS NULL)
AND (t1.Col3 IN (select * from dbo.SplitMe(@list)) OR @list IS NULL)