正文:
本文不是詳細講解代理作業的,僅僅從代理作業歷史表(dbo.sysjobhistory)的角度來學習和研究代理作業的執行時間。執行以下T-SQL代碼:
SELECT [job_id] ,[step_id] ,[run_status] ,[run_date] ,[run_time] ,[run_duration] FROM [dbo].[sysjobhistory] WHERE [run_duration] >= 1 ORDER BY [run_duration] DESC; GO
以上T-SQL的執行結果如下圖:
從以上圖中很容易看到字段列run_date、run_time和run_duration的數據格式。結合微軟聯機幫助文檔學習到:run_date字段列值的數據格式為yyyMMdd(該列值表示代理作業開始執行時的日期部分,如上圖run_date字段列值為20170316表示該作業開始執行於2017-03-16這個日期點),run_time字段列值的數據格式為hhmmss(該列值表示代理作業開始執行時的時間部分,如上圖run_time字段列值為20000表示執行於02:00:00這個時間點),run_duration字段列值的數據格式為hhmmss(這個是持續時間的數據格式,例如上圖中的dun_duration為127表示改作業執行從開始到完成共持續了1分27秒)。
通常情況下,我在數據表設計尤其涉及到記錄活動發生的日期時間點時更多的使用datetime這個數據類型的字段列。針對run_date和run_time的數據格式可以通過dbo.agent_datetime標量函數來轉換為datetime數據類型。執行以下T-SQL代碼:
SELECT [dbo].[agent_datetime](20170316, 20000) AS [run_datetime]; GO
以上T-SQL的執行結果如下圖:
那么如何將run_duration字段列值轉換為秒、分、小時等?下面繼續探究。
這個方法具體參考了dbo.agent_datetime函數的定義和
查看SQLServer 代理作業的歷史信息這邊博文中提供的方法,具體實現的T-SQL代碼如下:
SELECT [T1].[job_id] ,[T1].[name] AS [job_name] ,[T2].[run_status] ,[T2].[run_date] ,[T2].[run_time] ,[dbo].[agent_datetime]([T2].[run_date], [T2].[run_time]) AS [run_datetime] ,[T2].[run_duration] ,([T2].[run_duration] /10000 * 3600 + [T2].[run_duration] % 10000 / 100 * 60 + [T2].[run_duration] % 100 + 31) AS [run_duration_s] FROM [dbo].[sysjobs] AS [T1] INNER JOIN [dbo].[sysjobhistory] AS [T2] ON [T2].[job_id] = [T1].[job_id] WHERE [T1].[enabled] = 1 AND [T2].[step_id] = 0 AND [T2].[run_duration] >= 1 ORDER BY [T2].[job_id] ASC ,[T2].[run_date] ASC GO
以上T-SQL的執行結果如下圖:
注意:
- 這種方法才用了精度設置,默認精度為31秒,也就是說如果作業的執行持續時間超過30秒(包括等於30秒)時會自動增加31秒。
這個方法依然使用dbo.agent_datetime函數,還會增加dateadd函數和datediff函數。具體實現的T-SQL代碼如下:
SELECT [T1].[job_id] ,[T1].[name] AS [job_name] ,[T2].[run_status] ,[T2].[run_date] ,[T2].[run_time] ,[dbo].[agent_datetime]([T2].[run_date], [T2].[run_time]) AS [run_datetime] ,[T2].[run_duration] ,DATEDIFF(SECOND, '1900-01-01', DATEADD(SECOND, 31, [dbo].[agent_datetime](19000101, [run_duration]))) AS [run_duration_s] FROM [dbo].[sysjobs] AS T1 INNER JOIN [dbo].[sysjobhistory] AS T2 ON [T2].[job_id] = [T1].[job_id] WHERE [T1].[enabled] = 1 AND [T2].[step_id] = 0 AND [T2].[run_duration] >= 1 ORDER BY [T2].[job_id] ASC ,[T2].[run_date] ASC GO
以上T-SQL的執行結果如下圖:
注意:
- 該方法依然采用了默認精度為31秒。
- sql server系統提供的日期函數采用的默認基准日期是1900-01-01,這個可以使用0替代換。
通過研讀博友的文章和學習微軟聯機文檔,確實能夠學到很多的知識。sql 的路上唯有繼續修行,才能了解的更多。
