【问题标题】:Utilising optional parameters in where clause在 where 子句中使用可选参数
【发布时间】:2017-02-22 11:32:03
【问题描述】:

我在一个存储过程中有以下示例查询,其中@StartDate、@EndDate 和@ClientID 参数都是可选的。

在查询中处理该问题的最佳方法是什么,以确保我获得取决于 1 个或多个参数是否具有值的结果?

select * from table
WHERE
    StartDate >= @StartDate and
    StartDate <= @EndDate and
    CE.ClientID = @ClientID

例如,某人可以只输入开始日期或只输入结束日期或选择特定的 ClientID 或将所有 3 个组合起来。

【问题讨论】:

标签: sql-server


【解决方案1】:

如果您愿意在每次执行中牺牲少量时间,OPTION(RECOMPILE) 将提供与动态 SQL 相同的性能,但不会带来任何风险。

select * from table
WHERE
    (StartDate >= @StartDate or @StartDate is null) and
    (StartDate <= @EndDate or @EndDate is null) and
    (CE.ClientID = @ClientID or @ClientID is null)
option(recompile)

【讨论】:

  • 感谢院长,这个解决方案似乎是最好的,基于它的易用性。
【解决方案2】:

你可以这样做 -

SELECT * FROM table
WHERE
    (@StartDate IS NULL OR StartDate >= @StartDate) AND
    (@EndDate IS NULL OR StartDate <= @EndDate) AND
    (@ClientID IS NULL OR CE.ClientID = @ClientID)

【讨论】:

    【解决方案3】:

    最好的方法是使用动态 SQL。像这样的:

    declare @sql nvarchar(max);
    set @sql = 'select * from table';
    
    declare @where nvarchar(max);
    
    set @where = (case when @StartDate is not null then ' and StartDate >= @StartDate' else '' end) +
                 (case when @EndDate is not null then ' and EndDate >= @EndDate' else '' end) +
                 (case when @ClientID is not null then ' and ClientID = @ClientID' else '' end);
    
    set @where = stuff(@where, 1, 5, '');
    
    set @sql = @sql + (case when len(@where) > 0 then ' where ' + @where' else '');
    
    exec sp_executesql @sql,
                       N'@StartDate date, @EndDate date, @ClientId int',
                       @StartDate = @StartDate, @EndDate = @EndDate, @ClientId = ClientId;
    

    这样做更好的原因是每个可能的输入组合都会导致不同的查询。 SQL Server 可以使用适当的索引来优化查询,而这种优化在使用可选参数时非常重要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多