Sql server 使用多个可选条件对搜索屏幕的存储过程进行编码

Sql server 使用多个可选条件对搜索屏幕的存储过程进行编码,sql-server,stored-procedures,parameters,optional,Sql Server,Stored Procedures,Parameters,Optional,我有一个搜索屏幕,用户可以在上面指定名字、姓氏、学期或课程的任意组合。我不知道如何对SQLServer2005存储过程进行最佳编码,以处理这些潜在的可选参数。最有效的方法是什么?每个组合的单独程序?将项目作为可空参数放入并构建动态SQL?我将使用sp\u executesql来实现,因为计划将仅针对第一个模式或第一组条件进行缓存 看看这个: 当对Transact-SQL语句的参数值的更改是唯一的变化时,可以使用sp_executesql代替存储过程多次执行该语句。由于Transact-SQL语句

我有一个搜索屏幕,用户可以在上面指定名字、姓氏、学期或课程的任意组合。我不知道如何对SQLServer2005存储过程进行最佳编码,以处理这些潜在的可选参数。最有效的方法是什么?每个组合的单独程序?将项目作为可空参数放入并构建动态SQL?

我将使用sp\u executesql来实现,因为计划将仅针对第一个模式或第一组条件进行缓存

看看这个:


当对Transact-SQL语句的参数值的更改是唯一的变化时,可以使用sp_executesql代替存储过程多次执行该语句。由于Transact-SQL语句本身保持不变,并且只有参数值会更改,因此SQL Server查询优化器可能会在第一次执行时重用它生成的执行计划。

我会使用sp_executesql执行,因为该计划将仅针对第一个模式进行缓存,或者第一组条件

看看这个:


当对Transact-SQL语句的参数值的更改是唯一的变化时,可以使用sp_executesql代替存储过程多次执行该语句。由于Transact-SQL语句本身保持不变,并且只有参数值会更改,因此SQL Server查询优化器可能会在第一次执行时重用它生成的执行计划。

我会将每个参数设置为可选(默认值为null)

然后在哪里处理它

这将只处理名字、姓氏、所有三个等等


它也比动态构建SQL字符串并执行SQL字符串更漂亮、更易管理、更健壮。

我将每个参数设置为可选(默认值为null)

然后在哪里处理它

这将只处理名字、姓氏、所有三个等等


它也比动态构建SQL字符串并执行SQL字符串更漂亮、更易管理、更健壮。

刚刚发布了与Kevin Fairchild相同的概念,这就是我们通常处理它的方式


您可以根据需要在代码中使用动态sql来创建语句,但如果需要,您需要注意sql注入。

只是发布了与Kevin Fairchild相同的概念,这就是我们通常处理它的方式


您可以根据需要在代码中使用动态sql来创建语句,但如果需要,则需要注意sql注入。

正如muerte所指出的那样,将缓存第一组参数的计划。当它在以后每次使用备用参数运行时,这可能会导致性能下降。要解决这个问题,请在过程中使用WITH RECOMPILE选项。

正如muerte所指出的那样,将缓存计划中的第一组参数。当它在以后每次使用备用参数运行时,这可能会导致性能下降。要解决此问题,请在过程上使用WITH RECOMPILE选项。

最佳解决方案是使用sp\u execute\u 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()相比,这将有一个性能优势。

最好的解决方案是使用sp\u execute\u 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()相比,这将有一个性能优势。

如果使用sp_executesql,则需要确保不会引入任何SQL注入问题。因此,您的答案是“动态SQL”。不一定-问题是针对存储过程解决方案,在sp_executesql之前可能还有一些额外的逻辑。归根结底,真正的答案是,至少出于性能原因,应该尽量避免检查每个参数的空值。如果使用sp_executesql,则需要确保不会引入任何SQL注入问题。因此,您的答案是“动态SQL”。不必如此-问题是针对存储过程解决方案,在sp_executesql之前可能还有一些额外的逻辑。归根结底,真正的答案是,至少出于性能原因,应该尽量避免检查每个参数的空值。我同意,它更具可读性,但计划将仅针对第一个模式进行缓存,因此如果性能出现问题,执行动态sql可能是更好的解决方案。+1我也会这样做,但使用(@Paremeter为null或Column=@Paremeter)syntax在您开始使用确定联接的参数方向之前,此方法在性能上仍然相当不错,@muerte并且,作为一般规则,性能是可消耗的--可维护性/可读性不是;)您可以尝试进行一些优化,并从where子句中获取NULL。据我所知(这可能是注明日期的信息),当where子句中出现NULL参数时,MS SQL查询计划处理器从不重用缓存的查询计划。如果列可为NULL,则可能不希望这样。一旦用户没有为其中一个提供搜索词,任何具有空值的记录都将被排除。我同意,它更具可读性,但计划将仅针对第一个模式进行缓存,因此如果性能出现问题,执行动态sql可能是更好的解决方案。+1我也会这样做,但使用(@Paremeter为null或Column=@Paremeter)syntax在您开始使用确定联接的参数方向之前,此方法在性能上仍然相当不错,@muerte并且,作为一般规则,性能是可消耗的--可维护性/可读性不是;)您可以尝试进行一些优化,并从where子句中获取NULL。据我所知(这可能是注明日期的信息),当where子句中出现NULL参数时,MS SQL查询计划处理器从不重用缓存的查询计划。如果列可为NULL,则可能不希望这样。阿苏