使用SQL计划每月执行SSIS

时间:2012-05-03 22:55:04

标签: sql-server-2005 ssis sql-agent-job

我有一个SQL 2005 SSIS软件包,每月向政府办公室报告,每个月的最后一个星期四到期。我设置SQL Server以在正确的日子运行包。安排报告不是问题。

现在,SSIS包创建了一个月初至今的报告。我用了两个变量。 BeginDate,它使用表达式确定该月的第一天,并将其转换为类似“5/1/2012”的字符串。同样地,有和EndDate今天吐出像“5/3/2012”的日期。

有没有办法将BeginDate变量设置为上次运行报告后的第二天?有没有更好的方法来找出上个月最后一个星期四的日期?

1 个答案:

答案 0 :(得分:1)

有很多方法可以解决这个问题。

选项1

由于您使用的是SQL Agent,因此使用 SQL Agent。创建作业时,单击该框以确保您保存历史记录。假设您的数据库维护策略不会删除过去一个月的作业历史记录,您应该能够编写查询以确定作业步骤上次成功完成的时间。在执行SQL步骤中运行这样的查询将产生SSIS步骤上次成功运行的最后时间。您需要做的就是将第三个元素的值赋给EndDate变量

-- this query will find the most recent, successful execution of a job
-- named 'Last Thursday Of the Month job' with a job step of
-- 'The SSIS Step'
SELECT
    J.name AS job_name
,   JH.step_name AS job_step_name
,   MAX(msdb.dbo.agent_datetime(JH.run_date, JH.run_time)) AS execution_datetime
FROM 
    msdb.dbo.sysjobhistory JH
    INNER JOIN
        msdb.dbo.sysjobs J
        ON J.job_id = JH.job_id
    INNER JOIN
        msdb.dbo.sysjobsteps JS
        ON JS.job_id = J.job_id
            AND JS.step_id = JH.step_id
WHERE
    JH.run_status = 1
    AND J.name = 'Last Thursday Of the Month job'
    AND JH.step_name = 'The SSIS Step'
GROUP BY
    J.name
,   JH.step_name;

选项2

创建自定义表并让您的作业记录该表的最后处理日期。该过程在处理开始时查看该表,并使用最后一个日期作为结束日期。

CREATE TABLE dbo.AlmostEndOfTheMonth
(
    -- Can't use date as you're on 2005
    execution_date datetime
);

SELECT 
    MAX(AEOM.execution_date) AS most_recent_execution_date 
FROM 
    dbo.AlmostEndOfTheMonth AEOM;

选项3

用您最喜欢的语言计算一个月的最后一个星期四(.NET,TSQL,甚至可能SSIS表达语言都可以,但我不会尝试)

DECLARE
    @daysInWeek int
,   @dayOfWeek int
SELECT
    @daysInWeek = 7
,   @dayOfWeek = 5;

; WITH LAST_DAY_OF_PREVIOUS_MONTH (last_day_month) AS
(
    --http://blog.sqlauthority.com/2007/08/18/sql-server-find-last-day-of-any-month-current-previous-next/
    -- SQL 2012 makes this much easier with EOM and/or datefromparts functions
    SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))
)
,   LAST_THURSDAY_REFERENCE (last_thursday, last_day_month) AS
(
    SELECT CAST('2012-01-26' AS datetime), cast('2012-01-31' AS datetime)
    UNION ALL SELECT CAST('2012-02-23' AS datetime), cast('2012-02-29' AS datetime)
    UNION ALL SELECT CAST('2012-03-29' AS datetime), cast('2012-03-31' AS datetime)
    UNION ALL SELECT CAST('2012-04-26' AS datetime), cast('2012-04-30' AS datetime)
    UNION ALL SELECT CAST('2012-05-31' AS datetime), cast('2012-05-31' AS datetime)
    UNION ALL SELECT CAST('2012-06-28' AS datetime), cast('2012-06-30' AS datetime)
    UNION ALL SELECT CAST('2012-07-26' AS datetime), cast('2012-07-31' AS datetime)
    UNION ALL SELECT CAST('2012-08-30' AS datetime), cast('2012-08-31' AS datetime)
    UNION ALL SELECT CAST('2012-09-27' AS datetime), cast('2012-09-30' AS datetime)
    UNION ALL SELECT CAST('2012-10-25' AS datetime), cast('2012-10-31' AS datetime)
    UNION ALL SELECT CAST('2012-11-29' AS datetime), cast('2012-11-30' AS datetime)
    UNION ALL SELECT CAST('2012-12-27' AS datetime), cast('2012-12-31' AS datetime)
)
SELECT 
    *
    -- Thursday is the 5th day of the week, assuming you haven't messed with calendar's start of week
    -- We need to subtract up to 6 days from the end of the month to find the
    -- last Thursday. We can use the mod operator on ensure our dateadd function doesn't modify the
    -- date if the end of the month is actually Thursday, otherwise we want to back it off N days
    -- Examples might be easier to understand
    --  Last day    DayWeek     WeekdayNumber   DaysToSubtract
    --  2012-01-31  Tuesday     3               -5
    --  2012-02-29  Wednesday   4               -6
    --  2012-03-31  Saturday    7               -2
    --  2012-04-30  Monday      2               -4
    --  2012-05-31  Thursday    5               0
    --  2012-06-30  Saturday    7               -2
    --  2012-07-31  Tuesday     3               -5
    --  2012-08-31  Friday      6               -1
    --  2012-09-30  Sunday      1               -3
    --  2012-10-31  Wednesday   4               -6
    --  2012-11-30  Friday      6               -1
    --  2012-12-31  Monday      2               -4
,   dateadd(d, -((@daysInWeek - @dayOfWeek) + DATEPART(dw, LDM.last_day_month)) % @daysInWeek, LDM.last_day_month) AS last_thursday_of_month
FROM 
    LAST_DAY_OF_PREVIOUS_MONTH LDM
    -- Comment the above and uncomment the below to 
    -- evaluate all the dates in the 2012
    -- LAST_THURSDAY_REFERENCE LDM

选项4

与选项1类似,但使用SSIS日志记录,登录到SQL Server,然后查找上次成功执行日期并将其用作结束日期。

-- this code is approximate, I don't have a 2005 instance about
-- if you've logged to a different database, change the msdb reference
SELECT
    max(starttime) AS execution_datetime
FROM
    msdb.dbo.sysdtslog90 L
WHERE
    L.event = 'PackageStart'
    AND L.source = 'MyPackage';