我有一个搜索屏幕,用户可以在其上指定名字,姓氏,学期或课程的任意组合。我不确定如何优化代码SQL Server 2005存储过程来处理这些可能的可选参数。什么是最有效的方式?每个组合的单独程序?将项目作为可以为空的parms并构建动态SQL?
答案 0 :(得分:7)
我将每个参数设置为可选(默认值为null)
然后在 WHERE ....
中处理它FirstName=ISNULL(@FirstName,FirstName)
AND
LastName=ISNULL(@LastName,LastName)
AND
SemesterID=ISNULL(@SemesterID,SemesterID)
这只会处理名字,只处理姓氏,全部三个等等。
它比动态构建SQL字符串并执行它更加漂亮/可管理/健壮。
答案 1 :(得分:3)
最好的解决方案是使用sp_execute_sql。例如:
--BEGIN SQL
declare @sql nvarchar(4000)
set @sql =
'select * from weblogs.dbo.vwlogs
where Log_time between @BeginDate and @EndDate'
+ case when @UserName is null then '' else 'and client_user = @UserName' end
sp_execute_sql
@sql
, @params = '@UserName varchar(50)'
, @UserName = @UserName
--END SQL
正如muerte所提到的,与exec()的类似声明相比,这将具有性能优势。
答案 2 :(得分:0)
我会使用 sp_executesql 来执行此操作,因为计划将仅针对第一个模式或第一组条件进行缓存。
看看这个TechNet article:
当语句的参数值更改是唯一的变体时,可以使用sp_executesql代替存储过程多次执行Transact-SQL语句。由于Transact-SQL语句本身保持不变且只有参数值发生更改,因此SQL Server查询优化器可能会重用它为第一次执行时生成的执行计划。
答案 3 :(得分:0)
刚刚发布了与凯文费尔柴尔德相同的概念,这就是我们通常如何处理它。
您可以在代码中执行动态sql以根据需要创建语句,但如果需要,则需要注意sql注入。
答案 4 :(得分:0)
正如muerte指出的那样,该计划将被缓存为第一组参数。当使用备用参数随后每次运行时,这可能导致性能不佳。要解决这个问题,请使用过程中的WITH RECOMPILE选项。