【问题标题】:Select a Variable TimeSpan with an Arbitrary End point选择具有任意端点的可变时间跨度
【发布时间】:2009-04-29 16:09:50
【问题描述】:

我一直在研究一个检查时间的存储过程,然后检索从上午 8 点到前一个上午 8 点之间的最后一个完整 24 小时期间的记录。因此,例如,假设现在是上午 10 点。存储过程查看当前时间,指出它已超过上午 8 点,并将查询设置为 24 小时向后运行,从今天上午 8 点到昨天上午 8 点。例如,如果是上午 7 点,则查询将设置为从昨天上午 8 点到前一天上午 8 点进行检查。这实际上相对简单。 SP 旨在用于检索在给定时间跨度内完成的报告跟踪作业的记录。

但是,他们回过头来要求我更改存储过程,以便报告结束的时间和检查的时间跨度可以从网站的前端进行配置。我的 TimeSpan 工作时间大于或等于 24 小时,但在此范围内遇到了问题。到目前为止,这是我在存储过程中的逻辑 -

-- Retrieves data on jobs that completed/completed with errors during a given time span.
DECLARE @Hour NVARCHAR(2)
DECLARE @TimeFrame NVARCHAR(2)
DECLARE @TimeSpan INTEGER

SET @TimeSpan = 24
SET @TimeFrame = 'AM'
SET @Hour = '08'

DECLARE @dateStart DateTime
DECLARE @dateEnd DateTime

IF @TimeSpan < 24 -- Our TimeSpan is under one full day.
    BEGIN
            IF GETDATE() > DATEADD(hh, 0, DATEDIFF(hh, 0, GETDATE())) + (@Hour + ':00:00 ' + @TimeFrame)
            BEGIN
                SET @dateStart = DATEADD(hh, 0, DATEDIFF(hh, 0, GETDATE() - (1 + @TimeSpan))) + (@Hour + ':00:00 ' + @TimeFrame)
                SET @dateEnd =  DATEADD(hh, 0, DATEDIFF(hh, 0, GETDATE())) + (@Hour + ':00:00 ' + @TimeFrame)
            END
        ELSE
            BEGIN
                SET @dateStart = DATEADD(hh, 0, DATEDIFF(hh, 0, GETDATE() - (2 + @TimeSpan))) + (@Hour + ':00:00 ' + @TimeFrame)
                SET @dateEnd =  DATEADD(hh, 0, DATEDIFF(hh, 0, GETDATE() - 1)) + (@Hour + ':00:00 ' + @TimeFrame)
            END
    END
ELSE -- Our TimeSpan is at least one full day.
    BEGIN
        IF GETDATE() > DATEADD(D, 0, DATEDIFF(D, 0, GETDATE())) + (@Hour + ':00:00 ' + @TimeFrame)
            BEGIN
                SET @dateStart = DATEADD(D, 0, DATEDIFF(D, 0, GETDATE() - (1 + (@TimeSpan/24)))) + (@Hour + ':00:00 ' + @TimeFrame)
                SET @dateEnd =  DATEADD(D, 0, DATEDIFF(D, 0, GETDATE())) + (@Hour + ':00:00 ' + @TimeFrame)
            END
        ELSE
            BEGIN
                SET @dateStart = DATEADD(D, 0, DATEDIFF(D, 0, GETDATE() - (2 + (@TimeSpan/24)))) + (@Hour + ':00:00 ' + @TimeFrame)
                SET @dateEnd =  DATEADD(D, 0, DATEDIFF(D, 0, GETDATE() - 1)) + (@Hour + ':00:00 ' + @TimeFrame)
            END
    END

@Hour、@TimeFrame 和@TimeSpan 都是报表前端可以设置的参数,分别默认为'08'、'AM'和24。我知道在顶层 if 的 ELSE 部分中设置日期范围可以正常工作。我有理由确定设置小时偏移量的问题在于我在这里如何使用 DATEADD 和 DATEDIFF 函数,但我无法弄清楚我在哪里错过了一步。在这里的任何帮助将不胜感激。

【问题讨论】:

    标签: asp.net vb.net sql-server-2005


    【解决方案1】:
    -- convert the required end hour to 24 hour format
    DECLARE @EndHour INT
    SET @EndHour = CASE WHEN @TimeFrame = 'AM' THEN @Hour ELSE @Hour + 12 END
    
    -- set @DateEnd to the date-only portion of the current datetime
    -- ie, the time portion will be set to 00:00:00
    SET @DateEnd = DATEADD(day, 0, DATEDIFF(day, 0, GETDATE()))
    
    -- add the required end hour
    SET @DateEnd = DATEADD(hour, @EndHour, @DateEnd)
    
    -- if @DateEnd is in the future then subtract 24 hours from it
    IF @DateEnd > GETDATE()
       SET @DateEnd = DATEADD(hour, -24, @DateEnd)
    
    -- set @DateStart by subtracting the required timespan from @DateEnd
    SET @DateStart = DATEADD(hour, -@TimeSpan, @DateEnd)
    

    【讨论】:

    • 啊,这很好用,一旦我将小时更改为整数而不是 nvarchar。非常感谢,非常感谢您的帮助!
    • 我必须纠正一下——它比嵌套的 if 结构要简单得多,所以已经有了很大的改进,但它仍然存在同样的问题。它会选择的最短时间段是 24 小时。如果不到 24 小时,无论我要求什么,它仍然会出现 1 天的窗口。
    • @Clyde,我的代码可以正常工作,如上所述(您可以执行“SELECT @DateStart, @DateEnd”来验证这一点)。我怀疑问题出在您代码的其他地方,可能在您实际使用计算的开始日期和结束日期的查询中。你能发布那个查询吗?
    • 实际上,这正是我昨晚检查明显时间跨度问题的方式。就是说,我刚回去又试了一次——现在它显示了正确的时间跨度。在这一点上,我很确定我正在测试错误的代码 - 时间太长,一次处理太多事情,在我的经理中打开了太多选项卡,呵呵......再次感谢您的帮助。
    【解决方案2】:

    为什么不直接使用如下查询:

    SELECT something
    FROM aTable
    WHERE timeCompleted BETWEEN @StartDate AND @EndDate
    

    如果您担心时间是否正确(即日期必须是 '01/01/1900 13:00:00' 或类似的东西),只需单独传入日期并将时间作为函数添加到SQL。

    如果这不是您想要的,请包含更多 SQL,以便我们更好地了解您想要完成的任务。

    【讨论】:

    • 这实际上就是上面的 select 语句的含义。选择语句很简单。问题在于正确计算正确的日期以确定范围。以天为单位选择一个范围很容易,并且代码已经达到了这个效果。但是,他们希望同一份报告能够选择仅几个小时的范围,这就是问题所在。无论是在 VB 后端还是 SQL Server 中完成,在某些时候我都必须计算所选择的确切时间范围。
    猜你喜欢
    • 2017-10-11
    • 1970-01-01
    • 2014-12-13
    • 1970-01-01
    • 2011-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-11
    相关资源
    最近更新 更多