如何确定工作状态?

Vin*_*nod 43 sql t-sql stored-procedures sql-server-2005

我有一个存储过程来安排工作.这项工作需要很长时间才能完成(大约30到40分钟).我需要了解这份工作的状态.以下细节对我有帮助

1)如何查看已安排在未来时间但尚未开始的所有作业的列表

2)如何查看正在运行的作业列表以及它们运行时的时间跨度

3)如何查看作业是否已成功完成或由于任何错误而在两者之间停止.

efe*_*sar 76

我想指出,此页面上的T-SQL都不能正常工作,因为它们都没有加入syssessions表只能获取当前会话,因此可能包含误报.

请参阅此参考:具有空停止日期的作业意味着什么?

您还可以通过分析msdb中sp_help_jobactivity过程来验证这一点.

我意识到这是SO上的旧消息,但我发现这个消息只是部分有用,因为这个问题.

SELECT
    job.name, 
    job.job_id, 
    job.originating_server, 
    activity.run_requested_date, 
    DATEDIFF( SECOND, activity.run_requested_date, GETDATE() ) as Elapsed
FROM 
    msdb.dbo.sysjobs_view job
JOIN
    msdb.dbo.sysjobactivity activity
ON 
    job.job_id = activity.job_id
JOIN
    msdb.dbo.syssessions sess
ON
    sess.session_id = activity.session_id
JOIN
(
    SELECT
        MAX( agent_start_date ) AS max_agent_start_date
    FROM
        msdb.dbo.syssessions
) sess_max
ON
    sess.agent_start_date = sess_max.max_agent_start_date
WHERE 
    run_requested_date IS NOT NULL AND stop_execution_date IS NULL
Run Code Online (Sandbox Code Playgroud)

  • 这应该是答案.至少还有一个关于此问题的StackOverflow问题(此处:http://stackoverflow.com/questions/18445825/how-to-know-status-of-currently-running-jobs),其中一位评论者发现只是发现了sysjobactivity stop_execution_date为null的记录将包括几周之前显然还没有运行的run_requested_date的记录.我自己发现了同样的事情,当我查看卡住记录的session_ids时,我发现它们是以前的会话.上面运行@ efesar的查询排除了那些历史记录. (8认同)

Tim*_*m C 45

您可以尝试使用系统存储过程sp_help_job.这将返回有关作业,步骤,计划和服务器的信息.例如

EXEC msdb.dbo.sp_help_job @Job_name = 'Your Job Name'
Run Code Online (Sandbox Code Playgroud)

SQL Books Online应包含有关其返回的记录的大量信息.

要返回有关多个作业的信息,您可以尝试查询以下系统表,这些表保存有关作业的各种信息

  • msdb.dbo.SysJobs
  • msdb.dbo.SysJobSteps
  • msdb.dbo.SysJobSchedules
  • msdb.dbo.SysJobServers
  • msdb.dbo.SysJobHistory

他们的名字是相当不言自明的(除了SysJobServers,它持有关于工作上次运行和结果的信息).

同样,可以在MSDN上找到有关字段的信息.例如,查看SysJobs的页面

  • 需要使用表msdb.dbo.sysjobactivity来实际确定作业当前是否正在运行.表*msdb.dbo.sysjobhistory显然只在*作业(或步骤?)完成后才填充* - 并且根本没有填充"手动"作业(即不是来自作业计划). (6认同)

pie*_*rs7 27

这就是我用来获取正在运行的工作(主要是因为我可以杀死那些可能已挂起的工作):

SELECT
    job.Name, job.job_ID
    ,job.Originating_Server
    ,activity.run_requested_Date
    ,datediff(minute, activity.run_requested_Date, getdate()) AS Elapsed
FROM
    msdb.dbo.sysjobs_view job 
        INNER JOIN msdb.dbo.sysjobactivity activity
        ON (job.job_id = activity.job_id)
WHERE
    run_Requested_date is not null 
    AND stop_execution_date is null
    AND job.name like 'Your Job Prefix%'
Run Code Online (Sandbox Code Playgroud)

正如Tim所说,MSDN/BOL文档在sysjobsX表的内容上相当不错.请记住它们是MSDB中的表.


小智 12

-- Microsoft SQL Server 2008 Standard Edition:
IF EXISTS(SELECT 1 
          FROM msdb.dbo.sysjobs J 
          JOIN msdb.dbo.sysjobactivity A 
              ON A.job_id=J.job_id 
          WHERE J.name=N'Your Job Name' 
          AND A.run_requested_date IS NOT NULL 
          AND A.stop_execution_date IS NULL
         )
    PRINT 'The job is running!'
ELSE
    PRINT 'The job is not running.'
Run Code Online (Sandbox Code Playgroud)


Geo*_*ald 6

我使用评价最高的答案创建了一个简单的 SQL 函数来检查 SQL 代理作业是否已在运行:

-- ===================================================================================
-- Function: "IsJobAlreadyRunning"  |  Author: Geoff Griswald  |  Created: 2021-05-06
-- Description: Check if a SQL Agent Job is already Running - Return 1 if Yes, 0 if No
-- ===================================================================================
CREATE FUNCTION dbo.IsJobAlreadyRunning (@AgentJobName varchar(140))
RETURNS bit
AS
BEGIN
DECLARE @Result bit = 0
     IF EXISTS (SELECT job.name
                  FROM msdb.dbo.sysjobs_view job
            INNER JOIN msdb.dbo.sysjobactivity activity ON job.job_id = activity.job_id
            INNER JOIN msdb.dbo.syssessions sess ON sess.session_id = activity.session_id
            INNER JOIN (SELECT MAX(agent_start_date) AS max_agent_start_date
                          FROM msdb.dbo.syssessions) sess_max ON sess.agent_start_date = sess_max.max_agent_start_date
                 WHERE run_requested_date IS NOT NULL 
                   AND stop_execution_date IS NULL
                   AND job.name = @AgentJobName)
   SET @Result = 1
RETURN @Result
END;
Run Code Online (Sandbox Code Playgroud)

这很有用,因为我可以调用这个函数,并在尝试启动之前检查我想要启动的作业是否已经在运行,而不会给我的代码添加大量的臃肿。例如:

DECLARE @JobName varchar(140) = 'MyAgentJobName'
     IF (SELECT dbo.IsJobAlreadyRunning(@JobName)) = 0
   EXEC msdb.dbo.sp_start_job @JobName
Run Code Online (Sandbox Code Playgroud)