Гораздо лучший подход к этому состоит в том, чтобы не использовать WHILE
для чего-то, что может быть легко достигнуто с помощью метода, основанного на множестве. Использование WHILE
или CURSOR
обычно является ужасной идеей для чего-то, что может быть полностью выполнено методом, основанным на множествах, поскольку они медленны и плохо масштабируются.
Один из способов сделать это - использовать Tally, а затем построить на нем свой набор данных. Например:
USE Sandbox;
GO
DECLARE @StartDate date, @EndDate date;
SET @StartDate = '20180301';
SET @EndDate = '20180331';
WITH CTE AS (
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) V(N)),
Tally AS(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
FROM CTE C1
CROSS JOIN CTE C2),
Dates AS(
SELECT DATEADD(DAY,T.I, @StartDate) AS CalendarDate,
ROW_NUMBER() OVER (ORDER BY T.I DESC) AS Ir
FROM Tally T
WHERE T.I <= DATEDIFF(DAY, @StartDate, @EndDate))
SELECT D.CalendarDate, DATENAME(WEEKDAY,D.CalendarDate) AS CalendarDay
FROM Dates D
WHERE DATENAME(WEEKDAY,D.CalendarDate) NOT IN ('Saturday','Sunday') --Note this is language specific
OR Ir = 1
ORDER BY D.CalendarDate ASC;