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 = 0 BEGIN INSERT INTO BI_JOB_LOG --暫時記錄執行時間 SELECT GETDATE(); --執行業務邏輯代碼 ........................... END; IF @Minute = 0 AND @Hours%3=2 BEGIN INSERT INTO BI_JOB_LOG SELECT 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。 |