这有点复杂,但与上述答案有几个不同之处:它可以跨越午夜,处理不是 60 的因数的间隔(尝试上面的间隔为 7),并使用递归 CTE 生成数字而不是 WHILE 循环。
它对 INT 数据类型感到遗憾,具有 TSQL 的 TIME 数据类型的所有好处。您可以取消辅助功能。
MAXRECURSION 选项有时会出现问题,因为您不能在视图中使用它……调用语句必须指定它。为了解决这个问题,将它包装在一个多语句表值函数中。 看到这个帖子
CREATE FUNCTION dbo.ConvertIntToTime (@TimeAsInt INT)
RETURNS TIME
BEGIN
DECLARE @TimeString VARCHAR(4) = RIGHT(REPLICATE('0',4) + CAST(@TimeAsInt AS VARCHAR(4)),4);
RETURN PARSE(LEFT(@TimeString,2) + ':' + RIGHT(@TimeString,2) AS TIME);
END;
GO
CREATE FUNCTION dbo.ConvertTimeToInt (@Time TIME)
RETURNS INT
BEGIN
DECLARE @TimeString VARCHAR(5) = CONVERT(VARCHAR(5), @Time, 108);
RETURN PARSE(LEFT(@TimeString,2) + RIGHT(@TimeString,2) AS INT);
END;
GO
DECLARE @CurrentTime AS INT = 900;
DECLARE @EndTime AS INT = 1700;
DECLARE @Interval AS INT = 10;
DECLARE @CurrentTimeAsTime TIME = dbo.ConvertIntToTime(@CurrentTime);
DECLARE @EndTimeAsTime TIME = dbo.ConvertIntToTime(@EndTime);
WITH CTEGenerateTimes AS
(
SELECT @CurrentTimeAsTime Time
UNION ALL
SELECT DATEADD(MINUTE, @Interval, Time) AS TIME
FROM CTEGenerateTimes
WHERE (@EndTimeAsTime >= @CurrentTimeAsTime AND DATEADD(MINUTE, @Interval, Time) <= @EndTimeAsTime AND DATEADD(MINUTE, @Interval, Time) <> CAST('00:00' AS TIME)) --Range doesn't cross midnight
OR (@EndTimeAsTime < @CurrentTimeAsTime AND DATEADD(MINUTE, @Interval, Time) > @CurrentTimeAsTime AND DATEADD(MINUTE, @Interval, Time) <= CAST('23:59:59' AS TIME)) --Range crosses midnight, portion before midnight
OR (@EndTimeAsTime < @CurrentTimeAsTime AND DATEADD(MINUTE, @Interval, Time) <= @CurrentTimeAsTime AND DATEADD(MINUTE, @Interval, Time) <= @EndTimeAsTime)
)
SELECT dbo.ConvertTimeToInt(t.Time) Time
FROM CTEGenerateTimes t
OPTION (MAXRECURSION 1441)