SQL SERVER作業的Schedules淺析


    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,即表示這個時間點作為第一次執行的參照點。

 

clip_image002

 

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時才執行存儲過程。

 

clip_image004

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分鍾還是准時執行了。

clip_image006

要查看作業下次執行時間,可以通過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_type 的值

對 freq_interval 的影響

1(一次)

不使用 freq_interval (0)

4(每天)

freq_interval

8(每周)

freq_interval 為下列一個或多個值:

1 = 星期日

2 = 星期一

4 = 星期二

8 = 星期三

16 = 星期四

32 = 星期五

64 = 星期六

16(每月)

每月的 freq_interval

32(與“每月”選項相關)

freq_interval 為下列值之一:

1 = 星期日

2 = 星期一

3 = 星期二

4 = 星期三

5 = 星期四

6 = 星期五

7 = 星期六

8 = 日

9 = 工作日

10 = 休息日

64 (在 SQL Server 代理服務啟動時開始)

不使用 freq_interval (0)

128(在計算機空閑時運行)

不使用 freq_interval (0)

freq_subday_type

int

freq_subday_interval 的單位。可以是下列值之一:

說明(單位)

1

在指定的時間

2

4

分鍾

8

小時

freq_subday_interval

int

在每次執行作業之間發生的 freq_subday_type 的周期數。

freq_relative_interval

int

如果 freq_interval32(與“每月”選項相關),則為每月中 freq_interval 發生的時間。可以是下列值之一:

0 = 不使用 freq_relative_interval

1 = 第一次

2 = 第二次

4 = 第三次

8 = 第四次

16 = 最后一次

freq_recurrence_

factor

int

已計划執行的作業之間的周數或月數。僅當 freq_type81632 時,才使用 freq_recurrence_factor。如果此列包含 0,則不使用 freq_recurrence_factor

active_start_date

int

可以開始執行作業的日期。日期格式為 YYYYMMDD。NULL 表示當天的日期。

active_end_date

int

可以停止執行作業的日期。日期格式為 YYYYMMDD。

active_start_time

int

active_start_dateactive_end_date 之間的任意日期開始執行作業的時間。時間格式為 HHMMSS,采用 24 小時制。

active_end_time

int

active_start_dateactive_end_date 之間的任意日期停止執行作業的時間。時間格式為 HHMMSS,采用 24 小時制。

date_created

datetime

創建計划的日期和時間。

date_modified

datetime

上次修改計划的日期和時間。

version_number

int

計划的當前版本號。例如,如果計划已修改 10 次,則 version_number 為 10。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM