2017-02-22 129 views
0

我在存儲過程中的@StartDate,@EndDate和@ClientID參數都是可選的,我有以下示例查詢。在where子句中使用可選參數

在查詢中處理這個問題的最好方法是什麼,以確保我得到的結果取決於1個或多個參數是否具有值?

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

例如,有人可能只是輸入開始日期或只需輸入一個結束日期或選擇特定的客戶端ID或做的所有3

+2

的最佳參考,IMO,是厄蘭Sommarskog的[動態搜索條件在T-SQL](http://www.sommarskog.se/dyn-search.html) –

回答

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) 
+0

謝謝院長,這種解決方案似乎是最佳基於它的易用性。 – Philip

1

組合你可以做這樣的事情 -

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) 
1

最好的方法是使用動態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可以使用適當的索引來優化查詢,使用可選參數時,這種優化可能很重要。