2014-08-28 103 views
1

我正在创建用于搜索的存储过程。 DateOrdereddatetime类型表中的列名。如何在日期时间存储过程中使用BETWEEN

问题是我想对此列执行搜索。用户可以搜索开始日期和结束日期。另外,用户可以为任何参数发送null,例如开始日期或结束日期。

当用户不会发送开始日期或结束日期时,我将搜索另一个选项。我的问题是,我如何处理下面是我试过的查询,但没有成功

SELECT 
    @C_Order_ID = C_Order_ID 
FROM 
    C_Order COrder 
WHERE 
    (@AD_Org_ID IS NULL OR 
    COrder.AD_Org_ID IN (SELECT ID FROM fnSplitter(@AD_Org_ID))) 
    AND (@AD_Client_ID IS NULL OR 
     @AD_Client_ID IN (SELECT ID FROM fnSplitter(@AD_Client_ID))) 
    AND (@IsActive IS NULL OR COrder.IsActive = @IsActive) 
    AND (@startDate IS NULL OR 
     COrder.DateOrdered = @startDate BETWEEN @EndDate IS NULL 
      OR COrder.DateOrdered = @EndDate) 

感谢您的回复。

回答

1

你可以尝试这样的:

COrder.DateOrdered BETWEEN @startDate AND @EndDate 

所以,你的查询将会像

SELECT @C_Order_ID= C_Order_ID FROM C_Order COrder 
WHERE 
    (@AD_Org_ID IS NULL OR COrder.AD_Org_ID IN (Select ID From fnSplitter(@AD_Org_ID))) 
AND (@AD_Client_ID IS NULL OR @AD_Client_ID IN (Select ID From fnSplitter(@AD_Client_ID))) 
AND (@IsActive IS NULL OR COrder.IsActive = @IsActive) 
AND (@startDate IS NULL OR COrder.DateOrdered BETWEEN isnull(@startDate,'') AND isnull(@EndDate,'')) 

或更好

SELECT @C_Order_ID= C_Order_ID FROM C_Order COrder 
    WHERE 
     (@AD_Org_ID IS NULL OR COrder.AD_Org_ID IN (Select ID From fnSplitter(@AD_Org_ID))) 
    AND (@AD_Client_ID IS NULL OR @AD_Client_ID IN (Select ID From fnSplitter(@AD_Client_ID))) 
    AND (@IsActive IS NULL OR COrder.IsActive = @IsActive) 
    AND (CAST(@startDate AS DATE) IS NULL OR (CAST(@startDate AS DATE) IS NULL OR CAST(COrder.DateOrdered AS DATE) >=CAST(@startDate AS DATE)) 
    AND (CAST(@endDate AS DATE) IS NULL OR CAST(COrder.DateOrdered AS DATE) <=CAST(@endDate AS DATE)) 
+0

@ R.T。如果用户将发送空值然后 – 2014-08-28 07:12:38

+0

@ A.Goutam: - 更新我的答案来处理! – 2014-08-28 07:14:53

+0

但我的领域是类型的日期时间,我只想不为日期时间 – 2014-08-28 07:16:16

0
SELECT @C_Order_ID= C_Order_ID FROM C_Order COrder 
WHERE 
(@AD_Org_ID IS NULL OR COrder.AD_Org_ID IN (Select ID From fnSplitter(@AD_Org_ID))) 
AND (@AD_Client_ID IS NULL OR @AD_Client_ID IN (Select ID From fnSplitter(@AD_Client_ID))) 
AND (@IsActive IS NULL OR COrder.IsActive = @IsActive) 
AND (@startDate IS NULL OR COrder.DateOrdered BETWEEN @startDate AND @EndDate 
OR COrder.DateOrdered = @EndDate) 
+0

如果用户将发送空值,那么这将如何处理 – 2014-08-28 07:13:42

0

Aaron Bertrand已经撰写了有关使用的好文章与日期范围之间 - What do BETWEEN and the devil have in common?,这值得一读。此外,它看起来像你传递一个字符串中的逗号分隔的列表,然后用功能fnsplitter拆分它,你可能要考虑使用table-valued paramters

但是,要真正回答你的问题,你可以使用不使用上述想法之间并将您的查询更改为:

AND (@startDate IS NULL OR COrder.DateOrdered >= @startDate) 
AND (@EndDate IS NULL OR COrder.DateOrdered <= @EndDate) 

因此,您有4个排列组合。

  1. 两个@StartDate和@EndDate为空 - 返回所有日期
  2. @StartDate不是null @EndDate为空 - @StartDate后返回的所有日期
  3. @StartDate为null,并且@EndDate不空 - @EndDate
  4. 之前返回所有日期
  5. 两个@StartDate和@EndDate不是空 - 返回@StartDate和@EndDate

根据对另一个答案您的意见之间的所有日期,这听起来像你可能通过作为@EndDate参数的日期,例如2014-08-28,但仍希望包括该日期的所有记录,即使它们有时间相关,例如, 2014-08-28 12:00,这也正是为什么之间不使用的日期范围,而不是你需要使用不到运营商1天添加到您的结束日期:

AND (@startDate IS NULL OR COrder.DateOrdered >= @startDate) 
AND (@EndDate IS NULL OR COrder.DateOrdered < DATEADD(DAY, 1, @EndDate)) 
相关问题