我创建了一个名为 DesiredTimeOfFileCreation 的新列,类型为 time(7); 这将指示何时将数据提取到导出文件。
假设它设置为 6:00:00。然后,我在 6:00(可能每 30 分钟)安排了一个 SQL 代理作业,但它可能在 6:00:05 甚至 6:01 运行。我想选择 DesiredTimeOfFileCreation 小于 30 分钟前的所有行。
是否有人已经拥有用户定义的 TimeDiff 函数?还是有一个我想念的简单替代方案?
我创建了一个名为 DesiredTimeOfFileCreation 的新列,类型为 time(7); 这将指示何时将数据提取到导出文件。
假设它设置为 6:00:00。然后,我在 6:00(可能每 30 分钟)安排了一个 SQL 代理作业,但它可能在 6:00:05 甚至 6:01 运行。我想选择 DesiredTimeOfFileCreation 小于 30 分钟前的所有行。
是否有人已经拥有用户定义的 TimeDiff 函数?还是有一个我想念的简单替代方案?
正如马丁上面提到的,我需要处理午夜环绕。
这似乎过于复杂。如果一个时间是在午夜前一小时,而另一个是在午夜之后的一小时内,则下面的代码似乎可以工作。让它更通用会很好。我认为这样做的唯一方法是编一个虚拟日期,接下来我可能会尝试。
我在单元测试中传递日期的原因是我将传递 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
这可能对我有用:
WHERE DATEDIFF(Minute,DesiredFileCreationTimeLocal,cast(GETDATE() as time)) < 30
如果您将 Time 作为变量传递给 DateDiff 函数,我必须研究会发生什么。它似乎有效,唯一的技巧是如何传递两次给它。
我的现实世界场景更复杂,因为我们要处理不同时区的不同位置,所以上面会添加一些 UTC 转换。