1

我有一个应用程序,允许用户安排将来发生的操作。例如,可以选择一个日期并安排它在每个月的那一天运行(例如:每个月的 15 号)。但是,我现在需要允许他们选择一个月中的星期几和星期几。例如,他们需要在每月的第一个星期五执行一项操作。因此,我允许选择工作日(星期一、星期二、星期三......)和一个月中的一周(第 1、第 2、第 3、第 4 或第 5 日)。

这是我目前使用的查询:

Declare @nowString varchar(19)
        Declare @nowDateString varchar(19)
        Declare @now datetime
        Declare @lastMinute datetime
        Declare @nowDate datetime

        Set @nowString = '#currentDateTime#:00'
        Set @nowDateString = LEFT(@nowString, 10)
        set @now = @nowString
        set @nowDate = DATEADD(dd, 0, DATEDIFF(dd, 0, @now))
        set @lastMinute = DATEADD(mi, -1, @now)

        select * 
        from message_prepared
        where schedule = '1' 
        and active = '1'
        and noaa = '0'
        and (
            (
                schedule_type = 'recurring'
                and startdate <= @nowDate
                and isnull(enddate, DATEADD(yy, 1, @nowDate)) >= @nowDate
                and (
                    @nowDateString + ' ' + isnull(recurring_start_time_hour, '00') + ':' + isnull(recurring_start_time_min, '00') + ':00' = @now
                    or @nowDateString + ' ' + isnull(recurring_start_time_hour, '00') + ':' + isnull(recurring_start_time_min, '00') + ':00' = @lastMinute
                )
                -- Test for different type of recurring
                and (
                    ( ltrim(rtrim(recurring)) = 'M' and DATEPART(dd, startdate) = DATEPART(dd, @now) )
                    or ( ltrim(rtrim(recurring)) = 'W' and DATEPART(dw, startdate) = DATEPART(dw, @now) )
                    or ltrim(rtrim(recurring)) = 'D'
                )
            )
            or (
                schedule_type = 'once'
                and startdate = @nowDate
                and (
                    @nowDateString + ' ' + onetime_start_time_hour + ':' + onetime_start_time_min + ':00' = @now
                    or @nowDateString + ' ' + onetime_start_time_hour + ':' + onetime_start_time_min + ':00' = @lastMinute
                )
            )
        )
        and repeat_multiple_times = 0

        UNION ALL

        SELECT *
        FROM MESSAGE_PREPARED
        WHERE schedule = '1' 
        AND active = 1
        AND noaa = 0
        AND recurring = 'D'
        AND repeat_multiple_times = 1
        AND startDate IS NOT NULL
        AND recurring_start_time_hour IS NOT NULL
        AND recurring_start_time_hour < 24
        AND recurring_start_time_min IS NOT NULL
        AND recurring_start_time_min < 60
        AND startdate <= @nowDate
        AND ISNULL(enddate, DATEADD(yy, 1, @nowDate)) >= @nowDate
        AND
        ( 
            CASE WHEN repeat_unit = 'M'
                THEN
                DATEDIFF(n,
                CONVERT(DATETIME, 
                CAST(DATEPART(yyyy, startDate) AS VARCHAR(4)) + '-' + 
                CAST(DATEPART(mm, startDate) AS VARCHAR(2)) + '-' + 
                CAST(DATEPART(dd, startDate) AS VARCHAR(2)) + ' ' + 
                CAST(recurring_start_time_hour AS VARCHAR(2)) + ':' +
                CAST(recurring_start_time_min AS VARCHAR(2)) + ':00', 20),
                GETDATE()) % repeat_interval
                ELSE
                DATEDIFF(n,
                CONVERT(DATETIME, 
                CAST(DATEPART(yyyy, startDate) AS VARCHAR(4)) + '-' + 
                CAST(DATEPART(mm, startDate) AS VARCHAR(2)) + '-' + 
                CAST(DATEPART(dd, startDate) AS VARCHAR(2)) + ' ' + 
                CAST(recurring_start_time_hour AS VARCHAR(2)) + ':' +
                CAST(recurring_start_time_min AS VARCHAR(2)) + ':00', 20),
                GETDATE()) % (repeat_interval * 60)
            END = 0
            OR
            CASE WHEN repeat_unit = 'M'
                THEN
                (DATEDIFF(n,
                CONVERT(DATETIME, 
                CAST(DATEPART(yyyy, startDate) AS VARCHAR(4)) + '-' + 
                CAST(DATEPART(mm, startDate) AS VARCHAR(2)) + '-' + 
                CAST(DATEPART(dd, startDate) AS VARCHAR(2)) + ' ' + 
                CAST(recurring_start_time_hour AS VARCHAR(2)) + ':' +
                CAST(recurring_start_time_min AS VARCHAR(2)) + ':00', 20),
                GETDATE()) - 1) % repeat_interval
                ELSE
                (DATEDIFF(n,
                CONVERT(DATETIME, 
                CAST(DATEPART(yyyy, startDate) AS VARCHAR(4)) + '-' + 
                CAST(DATEPART(mm, startDate) AS VARCHAR(2)) + '-' + 
                CAST(DATEPART(dd, startDate) AS VARCHAR(2)) + ' ' + 
                CAST(recurring_start_time_hour AS VARCHAR(2)) + ':' +
                CAST(recurring_start_time_min AS VARCHAR(2)) + ':00', 20),
                GETDATE()) - 1) % (repeat_interval * 60)
            END = 0
        )

仅当重复设置为“M”时才会发生这种情况,我想确定今天是否是一周中的特定日期、一个月中的一周和小时/分钟。

4

1 回答 1

2

这是非常简单的逻辑。今天是本月的第 n 个 DOW,当以下情况成立时:

  1. 今天是一周中的那一天
  2. 月份中的日期介于 7*(n-1) + 1 和 7 * n 之间

因此,每个月的第一个星期一总是介于 1 号和 7 号之间,以此类推。这是一个示例case语句来测试它:

declare @DayOfWeek varchar(255) = 'Thursday';
declare @Which int = 3;

select (case when datename(dw, Today) = @DayOfWeek and
                  (DAY(Today) - 1) / 7 = @Which - 1
             then 1
             else 0
        end)
from (select CAST(getdate() as date) as Today) t

我以这种方式构造了查询,因此您可以使用不同的值对其进行测试。只需将定义 , 的表达式替换为or之Today类的东西。getdate() - 3'2013-01-01'

于 2013-06-20T18:32:56.403 回答