Сложная логика даты SQL: Как я могу запланировать свои отчеты? - PullRequest
4 голосов
/ 29 февраля 2012

У меня есть таблица, которая выглядит примерно так (упрощенно):

*ScheduledReports*
ReportID  
StartDate  
Frequency  
Interval (1=months, 2=days)

Так что, если бы я хотел запускать отчет каждые 3 дня, частота была бы равна 3, а интервал был бы равен 2.

Я пытаюсь написать хранимую процедуру, которую мы можем запускать один раз в день, которая будет запускать все отчеты из таблицы, запланированные на сегодня (или должна была выполняться с момента последнего запуска хранимой процедуры).,

Хранимая процедура также имеет доступ к lastRunTime (последний раз, когда эта хранимая процедура запускалась).

Вот как выглядит мой запрос:

-- get monthly reports that should be run
SELECT reportID
FROM ScheduledReports
WHERE intervalType = 1 AND
    dateadd(m,  (
           frequency * ceiling((
              --sql server calculates datediff of months based on the actual int of the month
              --not if it's a true month later, so the following is necessary to check for
              --a dayOfMonth difference
              CASE
                  WHEN startDate > @lastRunTime
                         THEN 0
                  WHEN day(startDate) > day(@lastRunTime)
                         THEN datediff(m, startDate, @lastRunTime) - 1
                  ELSE datediff(m, startDate, @lastRunTime)
                  END
              ) / (frequency*1.0))
           ), startDate) BETWEEN @lastRunTime AND getDate()

UNION ALL

-- get weekly reports that should be run 
SELECT reportID
FROM ScheduledReports
WHERE intervalType = 2 AND
    dateadd(d, (
           frequency * ceiling((
              CASE
                  WHEN startDate > @lastRunTime
                         THEN 0
                  ELSE datediff(d, startDate, @lastRunTime)
                  END
              ) / (frequency*1.0)
           )), startDate) BETWEEN @lastRunTime AND getDate()

Хотя с логикой что-то не так.Что не так с моей логикой?Как мне это сделать?

Ответы [ 2 ]

1 голос
/ 01 марта 2012

Хранимая процедура также имеет доступ к lastRunTime (последний раз, когда эта хранимая процедура была запущена).

Тебе не нужно знать, когда в последний раз создавался каждый отчет? И не последний раз, когда этот спрок был запущен? Каждый раз, когда вы запускаете sproc, каждый отчет может или не может быть создан. Чтобы узнать, прошел ли интервал для каждого отчета по каждому отчету (3 дня, 1 месяц и т. Д.), Вам необходимо знать, когда этот отчет последний раз создавался.

Что, если вы добавите в таблицу столбец даты LastReportRun. Тогда не проверяйте сегодняшнюю дату с @lastRunTime, а скорее с LastReportRun.

Report Run Today; Today = 2012/04/15

ID  StartDate   Freqcy  Interval  LastReportRun
--  ----------  ------  --------  ----------------  
1    2000/01/01  1      Days      2012/04/14         1 day ago;    print it
2    2000/01/01  14     Days      2012/04/09         6 days ago;   don`t print it
3    2000/01/01  3      Months    2012/01/13         > 3 mos ago;  print it
4    2000/01/01  3      Months    2012/01/17         < 3 mos ago;  don`t print it
0 голосов
/ 16 мая 2012

Нам удалось исправить ошибку - мы должны были добавить 1 в случае, а не вычитать, потому что мы хотим получить дату следующего запуска, а не предыдущую.Изменен регистр месяца на:

 CASE
        WHEN startDate > @lastRunTime
              THEN 0
        WHEN day(startDate) > day(@lastRunTime)
              THEN datediff(m, startDate, @lastRunTime)
        ELSE datediff(m, startDate, @lastRunTime) + 1
 END

, а регистр дня:

CASE
     WHEN startDate > @lastRunTime
        THEN 0
     ELSE datediff(d, startDate, @lastRunTime) + 1
END

И теперь он работает отлично:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...