DAYOFWEEK 里面 while

DAYOFWEEK inside while

过去一个小时我一直在研究这个,但似乎无法让它发挥作用。 我需要做的就是插入这些值,但我需要跳过包含星期六或星期日的插入。

Begin Tran

Declare @VaccID int = 26
Declare @Clinic int = 36
Declare @Enroll int = 30
Declare @SignUp int = 0
Declare @BlnAct int = 1
Declare @BlnDis int = 1
Declare @DateStartTime datetime =  '2015-09-16 11:00:00.000'
Declare @DateEndTime datetime = '2015-09-16 14:00:00.000'
Declare @EndDate date = '2015-10-16'
Declare @Days int = DATEDIFF(dd, @DateStartTime, @EndDate) 


Select @DateStartTime, @DateEndTime, @Days

Declare @i int = 0
Declare @WeekDay varchar = ''

WHILE @i <= @Days

IF(@WeekDay = 'Monday' OR 
   @WeekDay = 'Tuesday' OR 
   @WeekDay = 'Wednesday' OR 
   @WeekDay = 'Thursday' OR 
   @WeekDay = 'Friday')

Begin

INSERT INTO dbo.tblSessions 
           ([intVaccID],
            [intLocationID],
            [dtDateTimeStart],
            [dtDateTimeStop],
            [intEnrollmentMax],
            [intSignedUp],
            [blnActive],
            [blnDisplay])

Values (@VaccID, 
        @Clinic, 
        DATEADD(dd, @i, @DateStartTime), 
        DATEADD(dd, @i, @DateEndTime), 
        @Enroll, 
        @SignUp, 
        @BlnAct, 
        @BlnDis) 

SELECT @VaccID as intVaccID, 
       @Clinic as intLocationID, 
       DATEADD(dd, @i, @DateStartTime) as dtDateTimeStart, 
       DATEADD(dd, @i, @DateEndTime) as dtDateTimeStop, 
       @Enroll as intEnrollmentMax, 
       @SignUp as intSignedUp, 
       @BlnAct as blnActive, 
       @BlnDis as blnDisplay

SET @i = @i + 1
SET @WeekDay = DAYOFWEEK(dw, DATEADD(dd, @i, @DateStartTime))


END

Rollback Tran

Commit Tran

它至少在一周的每一天都在填写,但现在似乎在查询中途停滞不前。我知道我错过了一些可笑的小东西,但我似乎无法找到它。我想这是我今天的白鲸。

为什么不使用 GOTO 关键字跳过星期六和星期日:

实际上您的查询应该以其他方式重构。但是对于上面的场景你可以使用这个。

WHILE @i< @days
BEGIN


LABEL :
SET @i = @i + 1
SET @WeekDay = DAYOFWEEK(dw, DATEADD(dd, @i, @DateStartTime))

IF(@WeekDay = 'SATURDAY' OR @WeekDay = 'SUNDAY')
GOTO LABEL 

END

您应该将其作为基于集合的操作来执行,而不是使用循环。使用计数 table 时无需循环。看看这是否不会产生所需的输出。

Declare @VaccID int = 26
    , @Clinic int = 36
    , @Enroll int = 30
    , @SignUp int = 0
    , @BlnAct int = 1
    , @BlnDis int = 1
    , @DateStartTime datetime =  '2015-09-16 11:00:00.000'
    , @DateEndTime datetime = '2015-09-16 14:00:00.000'
    , @EndDate date = '2015-10-16';

WITH
    E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
    E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
    cteTally(N) AS 
    (
        SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1 FROM E4
    )

select @VaccID
    , @Clinic
    , DATEADD(dd, t.N, @DateStartTime)
    , DATEADD(dd, t.N, @DateEndTime)
    , @Enroll
    , @SignUp
    , @BlnAct
    , @BlnDis
from cteTally t
where t.N < = DATEDIFF(day, @DateStartTime, @EndDate)
and DATENAME(weekday, DATEADD(dd, t.N, @DateStartTime)) not in ('Saturday', 'Sunday');

@JBBeginner:更正您的查询,

Begin Tran

Declare @VaccID int = 26
Declare @Clinic int = 36
Declare @Enroll int = 30
Declare @SignUp int = 0
Declare @BlnAct int = 1
Declare @BlnDis int = 1
Declare @DateStartTime datetime =  '2015-09-16 11:00:00.000'
Declare @DateEndTime datetime = '2015-09-16 14:00:00.000'
Declare @EndDate date = '2015-10-16'
Declare @Days int = DATEDIFF(dd, @DateStartTime, @EndDate) 


Select @DateStartTime, @DateEndTime, @Days

Declare @i int = 0
Declare @WeekDay varchar = DAYOFWEEK(dw, @DateStartTime) -- changed

WHILE @i <= @Days
Begin                                                    -- changed

IF(@WeekDay = 'Monday' OR 
   @WeekDay = 'Tuesday' OR 
   @WeekDay = 'Wednesday' OR 
   @WeekDay = 'Thursday' OR 
   @WeekDay = 'Friday')

Begin

INSERT INTO dbo.tblSessions 
           ([intVaccID],
            [intLocationID],
            [dtDateTimeStart],
            [dtDateTimeStop],
            [intEnrollmentMax],
            [intSignedUp],
            [blnActive],
            [blnDisplay])

Values (@VaccID, 
        @Clinic, 
        DATEADD(dd, @i, @DateStartTime), 
        DATEADD(dd, @i, @DateEndTime), 
        @Enroll, 
        @SignUp, 
        @BlnAct, 
        @BlnDis) 

SELECT @VaccID as intVaccID, 
       @Clinic as intLocationID, 
       DATEADD(dd, @i, @DateStartTime) as dtDateTimeStart, 
       DATEADD(dd, @i, @DateEndTime) as dtDateTimeStop, 
       @Enroll as intEnrollmentMax, 
       @SignUp as intSignedUp, 
       @BlnAct as blnActive, 
       @BlnDis as blnDisplay

SET @i = @i + 1
SET @WeekDay = DAYOFWEEK(dw, DATEADD(dd, @i, @DateStartTime))

END

END                                                          -- changed

--Rollback Tran                                              -- changed

Commit Tran

递归 CTE 也适用于日期:

    Declare @DateStartTime datetime =  '2015-09-16 11:00:00.000'
    Declare @DateEndTime datetime = '2015-09-16 14:00:00.000'
    Declare @EndDate date = '2015-10-16'

    ;WITH cteDates AS (
            SELECT @DateStartTime AS StartDate, @DateEndTime AS EndDate, DATENAME(weekday, @DateStartTime) AS NameOfDay
            UNION ALL
            SELECT DATEADD(day, 1, cteDates.StartDate), DATEADD(day, 1, cteDates.EndDate), DATENAME(weekday, DATEADD(day, 1, cteDates.StartDate)) AS NameOfDay
            FROM cteDates
            WHERE DATEADD(day, 1, cteDates.StartDate) <= '2015-10-16'
    )
    -- INSERT INTO dbo.tblSessions ( ...)  -- Omitted for clarity
    SELECT * FROM cteDates
    WHERE NameOfDay NOT IN ('Saturday', 'Sunday')