我有一个搜索屏幕,用户可以在其中指定名字、姓氏、学期或课程的任意组合。我不确定如何以最佳方式对 SQL Server 2005 存储过程进行编码以处理这些潜在的可选参数。最有效的方法是什么?每个组合的单独程序?将项目作为可为空的参数并构建动态 SQL?
Caveatrob
问问题
5999 次
5 回答
7
我将每个参数设置为可选(默认值为空)
然后在WHERE ....
FirstName=ISNULL(@FirstName,FirstName)
AND
LastName=ISNULL(@LastName,LastName)
AND
SemesterID=ISNULL(@SemesterID,SemesterID)
那将只处理名字,只有姓氏,所有三个等等,等等。
它也比动态构建 SQL 字符串并执行它更漂亮/易于管理/健壮得多。
于 2009-02-17T21:54:59.060 回答
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() 类似的语句相比,这将具有性能优势。
于 2009-02-17T23:05:16.333 回答
0
我会使用sp_executesql来执行此操作,因为该计划将仅针对第一个模式或第一组条件进行缓存。
看看这篇TechNet 文章:
当语句的参数值更改是唯一的变化时,可以使用 sp_executesql 代替存储过程多次执行 Transact-SQL 语句。因为 Transact-SQL 语句本身保持不变并且只有参数值发生变化,所以 SQL Server 查询优化器可能会重用它为第一次执行生成的执行计划。
于 2009-02-17T21:49:43.457 回答
0
刚刚发布了与 Kevin Fairchild 相同的概念,这就是我们通常处理它的方式。
您可以在代码中执行动态 sql 以根据需要创建语句,但如果是这样,您需要注意 sql 注入。
于 2009-02-17T22:01:20.170 回答
0
正如 muerte 指出的那样,计划将为第一组参数缓存。当它每次使用备用参数运行时,这可能会导致性能下降。要解决这个问题,请在过程中使用 WITH RECOMPILE 选项。
于 2009-02-17T22:07:16.783 回答