0

我创建了一个名为 DesiredTimeOfFileCreation 的新列,类型为 time(7); 这将指示何时将数据提取到导出文件。

假设它设置为 6:00:00。然后,我在 6:00(可能每 30 分钟)安排了一个 SQL 代理作业,但它可能在 6:00:05 甚至 6:01 运行。我想选择 DesiredTimeOfFileCreation 小于 30 分钟前的所有行。

是否有人已经拥有用户定义的 TimeDiff 函数?还是有一个我想念的简单替代方案?

4

2 回答 2

1

正如马丁上面提到的,我需要处理午夜环绕。

这似乎过于复杂。如果一个时间是在午夜前一小时,而另一个是在午夜之后的一小时内,则下面的代码似乎可以工作。让它更通用会很好。我认为这样做的唯一方法是编一个虚拟日期,接下来我可能会尝试。

我在单元测试中传递日期的原因是我将传递 GetUTCDate() 的转换版本作为参数:

ALTER FUNCTION TimeDiffMinutes
(
    @FirstTime time(7), 
    @SecondTime time(7)

)
RETURNS int 
AS
BEGIN

/* 

Unit Test: 
   select dbo.TimeDiffMinutes('13:31',cast ('2013-06-10 13:35' as time)),  -- simple test 
          dbo.TimeDiffMinutes('23:55',cast ('2013-06-10 00:05' as time))   -- test midnight wrap-around 

   select dbo.TimeDiffMinutes('23:55',cast ('2013-06-10 00:05' as time))   -- test midnight wrap-around 

*/ 

    -- Declare the return variable here
    DECLARE @resultMinutes int 
    DECLARE @Hour int 

    -- although we can compare two times, the problem is that if one time is 11:55 and the other is 00:05, we want to show 10 minutes difference. 
    -- We cannot add 24 hours to a time, because that would be an invalid value 

    Set @Hour = datePart(hour,@SecondTime) 

    if (@Hour <= 0) 
      begin 
         -- increase both times by an hour so we can compare them, 23:55 will wrap around to 01:55
         Set @FirstTime = DateAdd(hour,+1,@FirstTime)
         Set @SecondTime = DateAdd(hour,+1,@SecondTime)
      end 

    SET @resultMinutes = DATEDIFF(Minute,@FirstTime,@SecondTime)                   


    -- Return the result of the function
    RETURN @resultMinutes 


END

注意:此代码表明您不能一次超过 24 小时;它只是回绕(没有错误!):

declare @FirstTime time(7)
SET @FirstTime = '23:05' 
print @FirstTime
Set @FirstTime = DATEADD(HOUR,1,@FirstTime)
print @FirstTime

改进版本,使用任意日期。

ALTER FUNCTION TimeDiffMinutes
(
    @FirstTime time(7), 
    @SecondTime time(7)

)
RETURNS int 
AS
BEGIN

/* 

Unit Test: 
   select dbo.TimeDiffMinutes('13:31',cast ('2013-06-10 13:35' as time)),  -- simple test 
          dbo.TimeDiffMinutes('23:55',cast ('2013-06-10 00:05' as time))   -- test midnight wrap-around 

   select dbo.TimeDiffMinutes('23:55',cast ('2013-06-10 00:05' as time))   -- test midnight wrap-around 

*/ 

    -- Declare the return variable here
    DECLARE @resultMinutes int 
    DECLARE @Hour int 
    DECLARE @FirstDate datetime 
    DECLARE @SecondDate datetime

    Set @FirstDate  = CAST('2001-01-01 ' + Convert(varchar(12),@FirstTime) as DateTime)
    Set @SecondDate = CAST('2001-01-01 ' + Convert(varchar(12),@SecondTime) as DateTime)


    -- although we can compare two times, the problem is that if one time is 11:55 and the other is 00:05, we want to show 10 minutes difference. 
    -- We cannot add 24 hours to a time, because that would be an invalid value 

    Set @Hour = datePart(hour,@SecondDate) 

    if (@Hour <= 0) 
      begin 
         -- increase both times by an hour so we can compare them, 23:55 will wrap around to 01:55
         Set @SecondDate = DateAdd(day,+1,@SecondDate)
      end 

    SET @resultMinutes = DATEDIFF(Minute,@FirstDate,@SecondDate)                   


    -- Return the result of the function
    RETURN @resultMinutes 


END

这就是我将如何使用该功能。我们将机场想要提取文件的本地时间存储在表中。然后我们将使用 SQL 代理或 BizTalk 每 30 分钟轮询一次以寻找工作要做。AirportCode 是表中的一列,我们有自己的疯狂函数来转换时区。

select *, 
       dbo.TimeDiffMinutes(
                DesiredFileCreationTimeLocal,
                cast(dbo.LocationLocalTimeFromAirportCode(AirportCode,GETUTCDATE()) as time)
                ) as 'MinutesAgo'
from TransactionExtractDistribution 
where    dbo.TimeDiffMinutes(
                DesiredFileCreationTimeLocal,
                cast(dbo.LocationLocalTimeFromAirportCode(AirportCode,GETUTCDATE()) AS time)
                ) < 30 
于 2013-06-10T18:54:28.283 回答
0

这可能对我有用:

 WHERE DATEDIFF(Minute,DesiredFileCreationTimeLocal,cast(GETDATE() as time)) < 30

如果您将 Time 作为变量传递给 DateDiff 函数,我必须研究会发生什么。它似乎有效,唯一的技巧是如何传递两次给它。

我的现实世界场景更复杂,因为我们要处理不同时区的不同位置,所以上面会添加一些 UTC 转换。

于 2013-06-10T16:29:43.523 回答