2013-03-27 79 views
0

我認爲這應該很簡單,但我仍然遇到問題。 我只想返回位於日期範圍之間的表中的所有數據。但我希望日期範圍是可選的。如何在SQL Server中傳遞可選的日期參數

ALTER PROCEDURE [dbo].[sp_ExistingPlacements_Get] 
    @DateFrom DATE = NULL, 
    @DateTo DATE = NULL 
AS 
BEGIN 
    SET NOCOUNT ON; 
    SELECT * 
    FROM tblExistingPlacements 
    WHERE 
     CreatedDT > COALESCE(NULLIF(@DateFrom, ''), @DateFrom) 
     AND 
     CreatedDT < COALESCE(NULLIF(@DateTo, GETDATE()), @DateTo) 
END 

所以,如果沒有日期傳入,我們返回整個表。

如果僅傳遞開始日期(DateFrom),則返回rows>開始日期和所有直到當前日期。

如果只有結束日期(dateTo)方法被傳遞,然後返回所有行<結束日期

當然,如果這兩個日期都過去了,其間返回這些日期的所有行。

我是否與COALESCE走錯了路線?

回答

3

不要這樣做。 SQL將不得不創建一個執行計劃,在任何情況下工作。儘管聽起來unituitive,最好是有三個獨立的查詢:

ALTER PROCEDURE [dbo].[sp_ExistingPlacements_Get] 
    @DateFrom DATE = NULL, 
    @DateTo DATE = NULL 
AS 
BEGIN 
    SET NOCOUNT ON; 
    IF (@DateFrom IS NULL and @DateTo IS NULL) 
     SELECT field, field, field 
     FROM tblExistingPlacements 
     WHERE CreatedDT < GETUTCDATE(); 
    ELSE IF (@DateFrom IS NULL) 
     SELECT field, field, field 
     FROM tblExistingPlacements 
     WHERE CreatedDT < @dateTo; 
    ELSE IF (@DateTo IS NULL) 
     SELECT field, field, field 
     FROM tblExistingPlacements 
     WHERE CreatedDT BETWEEN @DateFrom AND GETUTCDATE(); 
    ELSE 
     SELECT field, field, field 
     FROM tblExistingPlacements 
     WHERE CreatedDT BETWEEN @DateFrom AND @DateTo; 
END 

返回沒有指定參數,當整個表的智慧是非常值得懷疑的,但是這不是重點。再說:

  • 從來沒有在查詢中使用*,始終指定投影列表中明確
  • 總是使用UTC時間在數據庫中

有關此主題的深入討論見Dynamic Search Conditions in T-SQL

+0

謝謝你,Remus。 是的 - 我從來沒有真正使用*,但這是爲了方便解釋我的問題。 – wotney 2013-03-27 12:30:31

6

使用ISNULL(@parameter) OR (--your condition--)而不是COALESCE

BEGIN 
    SET NOCOUNT ON; 
    SELECT * 
    FROM tblExistingPlacements 
    WHERE 
     ((@DateFrom IS NULL) OR CreatedDT > @DateFrom) 
     AND 
     ((@DateTo IS NULL) OR CreatedDT < @DateTo) 
END 

如果參數未提供ISNULL回報TRUE,所以OR秒部分都不會有問題。

+0

感謝Marcin, 我收到錯誤:「ISNULL函數需要2個參數」 – wotney 2013-03-27 11:46:16

+0

@wotney更新了我的答案。請現在檢查一下。 – MarcinJuraszek 2013-03-27 11:47:31

+0

太棒了 - 非常感謝你! – wotney 2013-03-27 11:48:06