2013-02-06 39 views
0

我有以下存储过程:存储过程日期过滤造成任何记录

ALTER PROCEDURE [dbo].[GetErrorsByDate] 
(
    @p_skip INT 
    ,@p_take INT 
    ,@p_orderBy VARCHAR(50) = 'TimestampDesc' 
    ,@p_startDate SMALLDATETIME = NULL 
    ,@p_endDate SMALLDATETIME = NULL 
) 
AS 
BEGIN 

    WITH pathAuditErrorLogCT AS 
    (
     SELECT 
      CASE 
      WHEN @p_orderBy = 'TimestampAsc' THEN ROW_NUMBER() OVER (ORDER BY E.[Timestamp]) 
      WHEN @p_orderBy = 'TimestampDesc' THEN ROW_NUMBER() OVER (ORDER BY E.[Timestamp] DESC)           
      WHEN @p_orderBy = 'LogIdAsc' THEN ROW_NUMBER() OVER (ORDER BY E.LogId) 
      WHEN @p_orderBy = 'LogIdDesc' THEN ROW_NUMBER() OVER (ORDER BY E.LogId DESC)         
      WHEN @p_orderBy = 'ReferrerUrlAsc' THEN ROW_NUMBER() OVER (ORDER BY E.ReferrerUrl) 
      WHEN @p_orderBy = 'ReferrerUrlDesc' THEN ROW_NUMBER() OVER (ORDER BY E.ReferrerUrl DESC)          
      END AS RowNum 
      ,E.Id 
     FROM pathAuditErrorLog AS E 
     WHERE 
      (E.[Timestamp] >= @p_startDate OR @p_startDate IS NULL) 
     AND 
      (E.[Timestamp] <= @p_endDate OR @p_endDate IS NULL)      
    )     
    SELECT 
     E.Id 
    ,E.Node 
    ,E.HttpCode 
    ,E.[Timestamp] 
    ,E.[Version] 
    ,E.LogID 
    ,E.IsFrontEnd 
    ,E.ReferrerUrl 
    ,E.[Login] 
    ,E.BrowserName 
    ,E.BrowserVersion 
    ,E.ErrorDetails 
    ,E.ServerVariables 
    ,E.StackTrace 
    FROM pathAuditErrorLog AS E 

    INNER JOIN pathAuditErrorLogCT AS pct ON pct.Id = E.Id 

    WHERE pct.RowNum BETWEEN @p_skip + 1 AND (@p_skip + @p_take) 

    ORDER BY RowNum 
END 

的想法是,该程序从错误表返回数据,但允许动态列排序,分页和日期过滤。我的问题是日期筛选,这是公用表表达式的一部分。我无法正常工作。

如果我删除日期筛选逻辑,那么proc工作正常。随着它包括,那么即使有预期的行,我也经常没有返回行。例如,如果我尝试:

exec GetErrorsByDate 0, 10, 'TimestampDesc', '2013-02-05' 

只给出开始日期,然后我得到一堆记录备份。但是,如果我这样做:

exec GetErrorsByDate 0, 10, 'TimestampDesc', '2013-02-05', '2013-02-05' 

通过开始和结束日期,我最终没有记录返回。这很奇怪,因为我期望第一个查询中的一些记录出现在第二个查询中。

有人可以发现我做错了吗?

编辑: 我应用了AdaTheDev的建议,它看起来更接近我需要的东西。但是,我发现一种情况下,建议的方法不会返回我所期望的。如果我运行以下:

exec GetErrorsByDate 0, 10, 'TimestampDesc', '2013-01-01', '2013-01-03' 

我得到一行的时间戳是2013-01-02 13:29:00。如果我运行这个:

exec GetErrorsByDate 0, 10, 'TimestampDesc', '2013-01-01', '2013-01-02' 

我得不到任何行返回。我希望能够看到前一个查询的一行被返回,因为它的时间戳确实在2013年1月2日。我在这里误解了什么吗?

+0

在你的where子句中,你使用的是小写字母e,你给出了大写字母作为别名 – Meherzad

+0

干杯,我已经修复了错字,最初错过了。虽然这不能解决我正在经历的问题。 –

回答

2

这将只返回记录,其中Timestamp正是2013-02-05(即午夜),所以在那一天的记录将不会被包括(我假设他们都有相关的时间)。

如果要包括他们,我会改变子句:

WHERE 
      (e.[Timestamp] >= @p_startDate OR @p_startDate IS NULL) 
     AND 
      (e.[Timestamp] < @p_endDate OR @p_endDate IS NULL) 

(变化是现在@p_enddate条款只是<

然后执行:

exec GetErrorsByDate 0, 10, 'TimestampDesc', '2013-02-05', '2013-02-06' 
+0

啊,好的。我是否需要担心使用DATEADD DATEDIFF技术删除时间部分?你说的是有道理的,我把时间花在导致问题的等式上。 –

+0

你*可以*使用这样的技术*但是*你应该避免这样做 - 在你的WHERE子句中使用类似的函数会使查询不可靠 - 即,如果在Timestamp列上有合适的索引,会阻止索引被使用,从而影响性能。所以,最好坚持上面的方法。 – AdaTheDev