2012-05-03 70 views
0

我有一個SQL 2005 SSIS包,它每月向政府辦公室報告,這個政府辦公室每個月的最後一個星期四都會到位。我設置了SQL Server在正確的日期運行包。安排報告不是問題。每月使用SQL計劃執行SSIS

現在SSIS包創建了月份到日期報告。我使用了兩個變量。 BeginDate使用表達式來確定月份的第一天並將其轉換爲字符串,如「2012年5月1日」。同樣,還有和EndDate一樣的吐出今天的日期,如「5/3/2012」。

有沒有辦法將BeginDate變量設置爲上次運行報表後的那一天?有沒有更好的方法來找出上個月最後一個星期四的日期?

回答

1

有很多種方法可以解決這個問題。

選項1

由於您使用SQL代理,使用 SQL代理。創建作業時,請單擊該框以確保保存歷史記錄。假設您的數據庫維護策略不會刪除上個月的作業歷史記錄,那麼您應該能夠編寫一個查詢來確定作業步驟上次成功完成的時間。在執行SQL步驟中運行這樣的查詢將產生上次SSIS步驟成功運行的時間。所有你需要做的是第三個元素的值分配給您的結束日期變量

-- 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,然後查找上次成功的執行日期並將其用作您的enddate。

-- 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'; 
+0

我喜歡選項2,純粹是因爲它爲數據集成開發人員提供的控制。 :{> –

+0

由於Andy的原因,我選擇了2。如果我決定停止使用SQL Agent,那麼這個過程仍然會正常運行。 – nlinus