考虑以下采用一些参数的示例程序。
Create Procedure CustomerSearch(
@Name nVarChar(100) = Null,
@Phone nVarChar(100) = Null,
@Address nVarChar(100) = Null,
)
As
Select *
From dbo.CustomerView
Where (@Name is Null or Name = @Name) And
(@Phone is Null or Phone = @Phone) And
(@Address is Null or Address = @Address)
因为参数的值可能为null,所以我找到了处理它的两个解决方案。
在CustomerView视图中存在多个表连接,并且此表具有大量数据并且性能非常重要。解决方案1具有开销(执行计划)。由于某些原因,我无法使用Dynamic sql。有一种更好的方法来构建此查询吗?
当我使用条件@Name为Null或Name = @Name)而不是Name = @Name并查看执行计划时,索引寻求成本增加。
答案 0 :(得分:2)
上面发布的代码完全可以接受。如果性能有问题,请确保Name,Phone和Address列上有索引。
答案 1 :(得分:2)
您的代码工作正常,对于您的情况,我会将参数包装在NULLIF(@Parameter,'')中以防止空白被比较。
这是编写查询的另一种方式。如果参数为空或null,则它将列与自身进行比较,该列始终为true。
Name = COALESCE(NULLIF(@Name,''),Name)
答案 2 :(得分:1)
您可能还希望将OPTION (RECOMPILE)
添加到存储过程的末尾。
每当第一次在SQL Server中运行存储过程时,它都会进行优化,并在SQL Server的内存中编译和缓存查询计划。
来自MSDN article:
<强> RECOMPILE 强>
指示SQL Server数据库引擎在执行后丢弃为查询生成的计划,强制查询优化器在下次执行相同查询时重新编译查询计划。如果不指定 RECOMPILE ,数据库引擎会缓存查询计划并重新使用它们。编译查询计划时, RECOMPILE 查询提示使用查询中任何局部变量的当前值,如果查询位于存储过程中,则将当前值传递给任何参数。
RECOMPILE 是创建使用WITH RECOMPILE子句的存储过程的有用替代方法,当只需要重新编译存储过程内的查询子集而不是整个存储过程时。有关更多信息,请参阅重新编译存储过程。创建计划指南时, RECOMPILE 也很有用。