我有一个具有三个输入变量的存储过程:@ StartDate,@ EndDate)和@Type:
select t2.ID,
t1.DESC
from(select ID
from [dbo].[RI]
where [Date] between @StartDate and @EndDate) t2
left join [dbo].[R] t1 on t2.ID = t1.ID
where t1.DESC = @Type
问题是最后一个where条件。 T1.DESC始终具有三个可能的值之一(type1,type2或type3),但是在某些情况下,我想取消“ where-condition”,以便获得所有可能的值,就像未执行where-condition一样。如果@Type ='all',则取消该条件。有什么建议吗?
答案 0 :(得分:0)
我会使用IF / ELSE结构,但是如果给出Type的实际参数值,它将调用动态SQL。使用带有两个正则sql表达式的IF / ELSE结构的问题是,优化器将在首次使用传入的参数运行过程时编译所有这些查询。因此,您需要立即解决参数嗅探问题。
不是这样,通过使用动态SQL,一旦击中IF语句的那一侧,优化器将为动态SQL创建一个不同的计划,假设如果您在两个单独的过程中运行查询,则计划将有所不同。
所以您的proc可能看起来像这样(我没有检查语法):
String
答案 1 :(得分:0)
因此t1.DESC
可以包含type1
,type2
或type3
之类的值。如果要省略过滤器,请使用OR
来排除它。
WHERE
@Type = 'all' OR t1.DESC = @Type
如果您的参数为all
,则OR
将始终返回 true ,因此不会按t1.DESC
值进行过滤。如果不是all
,则t1.DESC
必须与@type
匹配。
您还可以使用IS NULL
来代替检查all
这样的固定值,该值取决于您的口味。
如果这是一个复杂的查询,那么在末尾添加OPTION (RECOMPILE)
可能很重要,因此考虑到参数的当前值,您迫使SQL引擎再次重新构建执行计划。使用WHERE
过滤器存储执行计划与不使用过滤器存储执行计划是不一样的(这就是'all'的情况。)