??? SQL SERVER作業的計劃(Schedules),如果你沒仔細研究過或沒有應用一些復雜的計劃(Schedules),那么你覺得SQL SERVER作業的計劃(Schedules)非常好用,也沒啥問題,但是我要告訴你一個“殘酷”的真相,相比Linux系統的Crontab,SQL SERVER作業的計劃其實是一個二等殘廢,很多功能要實行起來真的是讓人頭疼!
如果你自認為非常了解作業的配置(不要想當然,實踐驗證保證會讓你大吃一驚)?那么接下來先看看幾個問題:
1:如果你要配置作業在每個小時的第20分鐘執行,例如1:20、2:20、3:20........執行,你怎么配置?
2:在計劃(Schedules)里面,如果執行間隔為“小時”,那么取值必須為整數嗎? 可以為2.5個小時嗎?
3:在計劃(Schedules)里面,如果我要設置執行間隔為90分鐘計劃,這樣能行嗎?
4:如果我想在計劃(Schedules)外,多執行一次作業,如何執行? 執行了后,是否影響作業的計劃Schedules?
5: 修改系統時間,是否會影響作業的Schedule?
?
1:如果你要配置作業在每個小時的第20分鐘執行,例如1:20、2:20、3:20........執行,你怎么配置?
對于問題1這種類似的問題,如果你遇到過而且解決過這類問題,那么其實很簡單,你只需要設置開始時間為0:20即可,否則無法實現。至于SQL SERVER為什么要這么蛋疼的設置,應該是執行間隔有一個參照時間點(第一次執行的時間點),你設置開始開始時間為0:20,即表示這個時間點作為第一次執行的參照點。
?
?
2:在計劃(Schedules)里面,如果執行間隔為“小時”,那么取值必須為整數嗎? 可以為2.5個小時嗎?
關于問題2,答案是執行間隔是不能設成小數的,只能為整數,只能為1,2,3。。。。如果你將其值設置為一個小數,則當你點擊確定按鈕后,它會自動四舍五入變成一個整數,例如,你輸入1.3 ,你點擊確定后,再打開,你會發現其值變為1了,如果是1.6,則會變成2,不信的話,你可以試試。對于秒、分鐘都是如此。為什么如此呢,答案在于系統表msdb.dbo.sysschedules,不明白可以看文章最后。
?
3:在計劃(Schedules)里面,如果我要設置執行間隔為90分鐘計劃,這樣能行嗎?
如果沒有實踐過的人,肯定會信誓旦旦的說,那肯定可以啊。答案是設置執行間隔不能超過61,否則當你點擊確認的時候,系統自動會將其設為60,至于原因,我暫時沒有想明白,微軟這個限定,感覺真蛋疼。如果真有需求需要90分鐘執行一次,那怎么辦? 糾結了把。
方法1: 將作業J拆分成兩個一模一樣的作業J1 和J2,然后設置其Schedules為3小時執行一次,兩個作業錯開執行,剛好能滿足業務需求。不過想想都覺得麻煩!
?
方法2: 作業Schedule執行時間間隔90分鐘的實現方式是通過下面方式實現的:其實是將Schedule時間設為30分鐘執行一次,然后再代碼里面按其規律,達到90分鐘才真正執行業務邏輯SQL代碼。
2.1 從0:00(服務器時間)開始,作業Schedule的頻率為30分鐘一次,實際上只需要執行下面時間點(實際執行時間90分鐘),按規律可以分成兩種:
??????????? 整點執行的(0:00, 1:00, 2:00, 3:00…..) 只有當Hour %3 = 0 時才執行存儲過程。
??????????? 非整點執行的(0:30, 1:30, 2:30 ……......) 只有當Hour % 3= 1時才執行存儲過程。
2.2 從0:30(服務器時間)開始,作業Schedule的頻率為30分鐘一次,實際上只需要執行下面時間點,按規律也可以分成兩種。
??????????? 整點執行的(0:00, 1:00, 2:00, 3:00…..) 只有當Hour %3 = 2 時才執行存儲過程。
??????????? 非整點執行的(0:30, 1:30, 2:30 …….......) 只有當Hour % 3= 0時才執行存儲過程。
?
DECLARE @Hours INT;DECLARE @Minute INT;SELECT @Hours =CAST(SUBSTRING(CONVERT(VARCHAR(16), GETDATE(), 120),11,3) AS INT);SELECT @Minute=CAST(SUBSTRING(CONVERT(VARCHAR(16), GETDATE(), 120),15,2) AS INT);IF @Minute = 30 AND @Hours%3 = 0BEGIN INSERT INTO BI_JOB_LOG --暫時記錄執行時間SELECT GETDATE();--執行業務邏輯代碼 ...........................END;IF @Minute = 0 AND @Hours%3=2BEGININSERT INTO BI_JOB_LOGSELECT GETDATE();--執行業務邏輯代碼 ...........................END;
?
?
4:如果我想在計劃(Schedules)外,多執行一次作業,如何執行? 執行了后,是否影響作業的計劃Schedules?
如下圖所示,我建立一個測試作業test,每隔13分鐘執行一次,在21:57, 21:58我分別手動執行了該作業兩次,但是絲毫不影響該作業的調度計劃。在22:06分鐘還是準時執行了。
要查看作業下次執行時間,可以通過SELECT * FROM msdb.dbo.sysjobschedules 來查看。
?
5: 修改系統時間,是否會影響作業的Schedule?
? 答案是會影響,一般要么重建該作業的調度計劃或禁用作業的調度,再啟用該調度來解決。有興趣的可以自己試驗一下,這里不做過多介紹。
SQL SERVER數據庫作業的 Schedule 信息一般位于表 msdb.dbo.sysschedules,如下所示
包含有關 SQL Server 代理作業計劃的信息。此表存儲在 msdb 數據庫中。其實看其參數的數據類型,你就知道第二個問題的答案了。呵呵
列名 | 數據類型 | 說明 | ||||||||||||||||
schedule_id | int | SQL Server 代理作業計劃 ID。 | ||||||||||||||||
schedule_uid | uniqueidentifier | 作業計劃的唯一標識符。此值用于標識分布式作業的計劃。 | ||||||||||||||||
originating_server_id | int | 作為作業計劃來源的主服務器 ID。 | ||||||||||||||||
name | sysname (nvarchar(128)) | 作業計劃的用戶定義名稱。該名稱在作業中必須唯一。 | ||||||||||||||||
owner_sid | varbinary(85) | 擁有作業計劃的用戶或用戶組的 Microsoft Windows security_identifier。 | ||||||||||||||||
enabled | int | 作業計劃的狀態: 0 = 未啟用。 1 = 啟用。 如果未啟用計劃,則不會運行該計劃中的任何作業。 | ||||||||||||||||
freq_type | int | 此計劃中作業運行的頻率。 1 = 只運行一次 4 = 每天 8 = 每周 16 = 每月 32 = 每月,與 freq_interval 有關 64 = 在 SQL Server 代理服務啟動時運行 128 = 在計算機空閑時運行 | ||||||||||||||||
freq_interval | int | 執行作業的間隔天數。該值取決于 freq_type 的值。默認值為 0,表示不使用 freq_interval。
| ||||||||||||||||
freq_subday_type | int | freq_subday_interval 的單位。可以是下列值之一:
| ||||||||||||||||
freq_subday_interval | int | 在每次執行作業之間發生的 freq_subday_type 的周期數。 | ||||||||||||||||
freq_relative_interval | int | 如果 freq_interval 為 32(與“每月”選項相關),則為每月中 freq_interval 發生的時間。可以是下列值之一: 0 = 不使用 freq_relative_interval 1 = 第一次 2 = 第二次 4 = 第三次 8 = 第四次 16 = 最后一次 | ||||||||||||||||
freq_recurrence_ factor | int | 已計劃執行的作業之間的周數或月數。僅當 freq_type 為 8、16 或 32 時,才使用 freq_recurrence_factor。如果此列包含 0,則不使用 freq_recurrence_factor。 | ||||||||||||||||
active_start_date | int | 可以開始執行作業的日期。日期格式為 YYYYMMDD。NULL 表示當天的日期。 | ||||||||||||||||
active_end_date | int | 可以停止執行作業的日期。日期格式為 YYYYMMDD。 | ||||||||||||||||
active_start_time | int | 在 active_start_date 和 active_end_date 之間的任意日期開始執行作業的時間。時間格式為 HHMMSS,采用 24 小時制。 | ||||||||||||||||
active_end_time | int | 在 active_start_date 和 active_end_date 之間的任意日期停止執行作業的時間。時間格式為 HHMMSS,采用 24 小時制。 | ||||||||||||||||
date_created | datetime | 創建計劃的日期和時間。 | ||||||||||||||||
date_modified | datetime | 上次修改計劃的日期和時間。 | ||||||||||||||||
version_number | int | 計劃的當前版本號。例如,如果計劃已修改 10 次,則 version_number 為 10。 |