我想补充 Mladen Prajdic 的正确答案,并改进来自 SQL Server Central 的 kevchadders 的答案。我在下面提出的解决方案使用 DBMail 而不是 SQLMail(SQLServerCentral 的解决方案通过 xp_sendmail 调用使用它)。本质上,SQLMail 使用 MAPI,更难设置,而 DBMail 使用 SMTP,更容易设置。这是more information关于两者之间的区别。
我无法让 SQL Server Central 的解决方案在 SQL 2005 中运行,并且以下解决方案仅在我安装的 SQL 2005 - 基于版本的 YMMV 上进行了测试。
首先,您需要一个新的 UDF,它将作业 ID 转换为 JOIN 的进程 ID:
CREATE FUNCTION dbo.udf_SysJobs_GetProcessid(@job_id uniqueidentifier)
RETURNS VARCHAR(8)
AS
BEGIN
RETURN (substring(left(@job_id,8),7,2) +
substring(left(@job_id,8),5,2) +
substring(left(@job_id,8),3,2) +
substring(left(@job_id,8),1,2))
END
然后是存储过程:
CREATE PROC sp_check_job_running
@job_name char(50),
@minutes_allowed int,
@person_to_notify varchar(50)
AS
DECLARE @minutes_running int,
@message_text varchar(255)
SELECT @minutes_running = isnull(DATEDIFF(mi, p.last_batch, getdate()), 0)
FROM master..sysprocesses p
JOIN msdb..sysjobs j ON dbo.udf_sysjobs_getprocessid(j.job_id) = substring(p.program_name,32,8)
WHERE j.name = @job_name
IF @minutes_running > @minutes_allowed
BEGIN
SELECT @message_text = ('Job ' + UPPER(SUBSTRING(@job_name,1,LEN(@job_name))) + ' has been running for ' + SUBSTRING(CAST(@minutes_running AS char(5)),1,LEN(CAST(@minutes_running AS char(5)))) + ' minutes, which is over the allowed run time of ' + SUBSTRING(CAST(@minutes_allowed AS char(5)),1,LEN(CAST(@minutes_allowed AS char(5)))) + ' minutes.')
EXEC msdb.dbo.sp_send_dbmail
@recipients = @person_to_notify,
@body = @message_text,
@subject = 'Long-Running Job to Check'
END
可以轻松地将这个存储过程安排为 SQL Server 代理作业或任何其他必要的方法。如果作业未运行或在指定参数内运行,则不执行任何操作。如果作业运行时间超过指定时间,它会发送电子邮件。
例如
EXEC sp_check_job_running 'JobNameGoesHere', 5, 'admin@mycompany.com'
HT:http://www.sqlserverspecialists.co.uk/blog/_archives/2008/11/26/3996346.html