用于添加日期+3个工作日(不包括周末和节假日)的功能

时间:2019-05-17 03:28:41

标签: sql sql-server sql-server-2012

我正在编写一个具有2个参数的函数,即datenow和'3',用于添加日期+ 3个工作日。

我已经成功地为周末添加了date + 3个工作日,但是对于假期,结果却不是我期望的,对于假期,我有一个名为lkp_holiday的表 想法是获取当前日期并检查lkp_holiday上的日期,如果有相同的日期,则添加addDate

ALTER FUNCTION [dbo].[DATEADDEXCLUDEWD](@addDate AS DATE, @numDays AS INT)
RETURNS DATETIME
AS
BEGIN
  DECLARE @DateHoliday DATETIME

  WHILE @numDays > 0
  BEGIN
    SET @addDate = DATEADD(d, 1, @addDate)
      --For weekend
    IF DATENAME(DW, @addDate) = 'saturday' SET @addDate = DATEADD(d, 1, @addDate)
    IF DATENAME(DW, @addDate) = 'sunday' SET @addDate = DATEADD(d, 1, @addDate)
      --For Holiday
      IF EXISTS(SELECT DISTINCT hol_date  FROM [Vacation].[dbo].[Lkp_Holiday] WHERE hol_date > GETDATE())
      BEGIN
          DECLARE M_CURSOR CURSOR
          FOR SELECT DISTINCT hol_date  FROM [Vacation].[dbo].[Lkp_Holiday] WHERE hol_date > GETDATE()

          OPEN M_CURSOR
          FETCH NEXT FROM M_CURSOR INTO @DateHoliday

          WHILE @@FETCH_STATUS = 0
          BEGIN
              SET @addDate = DATEADD(DAY, 1, @addDate)

              FETCH NEXT FROM M_CURSOR INTO @DateHoliday
          END
          CLOSE M_CURSOR
          DEALLOCATE M_CURSOR
      END                                         

    SET @numDays = @numDays - 1
  END

  RETURN CAST(@addDate AS DATETIME)
END

例如今天是2019-05-17,加上3天,输出2019-05-22 = >>是真的,因为它包括周末

我已经运行了该函数,并且在lkp_holiday表中我有一个约会假期,比如说2019-05-23

我期望的是2019-05-24,但是此函数的结果是2019-05-25

1 个答案:

答案 0 :(得分:1)

正如其他人指出的那样,这远不是解决此问题的最佳方法。但是,随着代码的正常运行,存在以下问题,在以下代码中已得到纠正:

  1. 您需要检查假日日期是否是循环所处理的日期,否则,您需要在每次循环中添加假日日期。

  2. 为此,您需要将@DateHoliday变量的类型设置为date而不是datetime。

  3. 为确保周末跳过代码有效,您需要在添加

  4. 之前应用
  5. “假期”在“ 2019-05-23”的“ 2019-05-17”输出仍然是“ 2019-05-22”,但是现在“ 2019-05-18”的输出“ 2019-05-24”,即添加了另一天作为假日。

    ALTER FUNCTION [dbo].[DATEADDEXCLUDEWD]
    (
      @addDate AS DATE
      , @numDays AS INT
    )
    RETURNS DATETIME
    AS
    BEGIN
      -- Needs to be a date type to allow for a date to date compare in the holiday section
      DECLARE @DateHoliday DATE

      WHILE @numDays > 0
      BEGIN
          --For weekend

        -- Add these before the regular add date, as otherwise we've already moved the date forward 1 day
        IF DATENAME(DW, @addDate) = 'saturday' SET @addDate = DATEADD(d, 1, @addDate)
        IF DATENAME(DW, @addDate) = 'sunday' SET @addDate = DATEADD(d, 1, @addDate)

        SET @addDate = DATEADD(d, 1, @addDate)

          --For Holiday
          IF EXISTS(SELECT DISTINCT hol_date FROM [Vacation].[dbo].[Lkp_Holiday] WHERE hol_date > GETDATE())
          BEGIN
              DECLARE M_CURSOR CURSOR
              FOR SELECT DISTINCT hol_date FROM [Vacation].[dbo].[Lkp_Holiday] WHERE hol_date > GETDATE()

              OPEN M_CURSOR
              FETCH NEXT FROM M_CURSOR INTO @DateHoliday

              WHILE @@FETCH_STATUS = 0
              BEGIN
            -- Only add the day if we've on the holiday day
            if @DateHoliday = @addDate begin
                  SET @addDate = DATEADD(DAY, 1, @addDate)
            end

                  FETCH NEXT FROM M_CURSOR INTO @DateHoliday
              END
              CLOSE M_CURSOR
              DEALLOCATE M_CURSOR
          END                                     

        SET @numDays = @numDays - 1
      END

      RETURN CAST(@addDate AS DATETIME)
    END