Функция добавления даты +3 рабочих дня, исключая выходные и праздничные дни - PullRequest
0 голосов
/ 17 мая 2019

Я пишу функцию с 2 параметрами, datenow и '3' для добавления даты + 3 рабочих дня.

Я успешно добавил дату + 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 Ответ

1 голос
/ 17 мая 2019

Как уже отмечали другие, это далеко не лучший способ решить эту проблему.Однако, чтобы заставить ваш код работать, есть следующие проблемы, исправленные в следующем коде:

  1. Вы должны были проверить, что праздничная дата была датой, обрабатываемой циклом, иначеВы добавляли его каждый раз, когда проходили цикл.

  2. Для этого вам нужно, чтобы переменная @DateHoliday имела тип date, а не datetime.

  3. Чтобы убедиться, что код пропуска в выходные дни работает, вам нужно применить его до , добавить день

  4. Также вывод "2019-05-17""с выходным днем" 2019-05-23 "по-прежнему" 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
...