Как определить статус задания?

У меня есть хранимая процедура, которая планирует работу. Это задание занимает много времени, чтобы завершить работу (приблизительно 30-40 минут). Мне нужно узнать статус этого задания. Ниже детали помогут мне

1) Как просмотреть список всех заданий, которые были запланированы на будущее и еще не начались

2) Как просмотреть список выполняемых заданий и временной интервал с момента их запуска

3) Как узнать, успешно ли выполнено задание или остановилось между ними из-за какой-либо ошибки.

Вы можете попробовать использовать хранимую процедуру системы sp_help_job. Это возвращает информацию о задании, его шагах, расписаниях и серверах. Например

EXEC msdb.dbo.sp_help_job @Job_name = 'Your Job Name' 

SQL Books Online должен содержать много информации о возвращаемых им записях.

Для возврата информации о нескольких заданиях вы можете попробовать запросить следующие системные таблицы, в которых хранятся различные биты информации о работе

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

Их имена достаточно понятны (кроме SysJobServers, которые содержат информацию о том, когда работа была выполнена, и результат).

Опять же, информацию о полях можно найти в MSDN. Например, проверьте страницу для SysJobs

Я хотел бы отметить, что ни один из T-SQL на этой странице не будет работать именно потому, что ни один из них не присоединяется к таблице syssessions, чтобы получить только текущий сеанс и поэтому может включать ложные срабатывания.

См. Это для справки: что значит иметь работу с нулевой остановкой?

Вы также можете проверить это, проанализировав процедуру sp_help_jobactivity в msdb .

Я понимаю, что это старое сообщение на 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 

Это то, что я использую, чтобы получить текущие задания (в основном, чтобы я мог убить те, которые, вероятно, зависали):

 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%' 

Как сказал Тим, документация MSDN / BOL достаточно хороша в содержании таблиц sysjobsX. Просто помните, что это таблицы в MSDB.

 -- 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.' 

мы можем запросить msdb во многих отношениях, чтобы получить детали.

немногие

 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%' 

Вы не указали, как бы вы хотели видеть эти детали.

Для первого взгляда я предлагаю проверить Server Management Studio .

В разделе «Рабочие места» вы можете увидеть задания и текущие статусы в компоненте агента SQL Server. Если вы выбираете задание, на странице свойств отображается ссылка на журнал заданий, где вы можете увидеть время начала и окончания, если есть какие-либо ошибки, какой шаг вызвал ошибку и т. Д.

Вы можете указать оповещения и уведомления для отправки по электронной почте или на странице, когда задание завершилось успешно или завершилось неудачно.

Существует Монитор активности работы, но на самом деле я никогда не использовал его. Вы можете попробовать.

Если вы хотите проверить это через T-SQL, то я не знаю, как вы можете это сделать.

Один из эффективных и правильных способов получить отчет «Статус запуска» в SSRS для упрощения просмотра и мониторинга заданий, выполняемых на серверах. (файл .rdl прилагается.) http://www.sqllion.com/2011/11/job-running-status-report-in-ssrs/

Вышеупомянутые задачи работают, но я видел много записей в msdb.dbo.sysjobactivity, где run_Requested_date не имеет значения null и stop_execution_date имеет значение null —- и задание в настоящий момент не выполняется.

Я бы рекомендовал запустить следующий скрипт, чтобы очистить все фиктивные записи (убедитесь, что в это время не выполняются задания).

SQL2008:

  delete activity from msdb.dbo.sysjobs_view job inner join msdb.dbo.sysjobactivity activity on job.job_id = activity.job_id where activity.run_Requested_date is not null and activity.stop_execution_date is null 

Это старый вопрос, но у меня была аналогичная ситуация, когда мне нужно было проверить статус заданий на SQL Server. Многие люди упомянули таблицу sysjobactivity и указали на документацию MSDN, которая великолепна. Тем не менее, я также хотел бы выделить Монитор активности работы, который обеспечивает статус всех заданий, определенных на вашем сервере.

Самый простой способ, который я нашел, – создать хранимую процедуру. Введите «JobName» и нажмите «Go».

 /*----------------------------------------------------------------------------------------------------------- Document Title: usp_getJobStatus Purpose: Finds a Current Jobs Run Status Input Example: EXECUTE usp_getJobStatus 'MyJobName' -------------------------------------------------------------------------------------------------------------*/ IF OBJECT_ID ( 'usp_getJobStatus','P' ) IS NOT NULL DROP PROCEDURE usp_getJobStatus; GO CREATE PROCEDURE usp_getJobStatus @JobName NVARCHAR (1000) AS IF OBJECT_ID('TempDB..#JobResults','U') IS NOT NULL DROP TABLE #JobResults CREATE TABLE #JobResults ( Job_ID UNIQUEIDENTIFIER NOT NULL, Last_Run_Date INT NOT NULL, Last_Run_Time INT NOT NULL, Next_Run_date INT NOT NULL, Next_Run_Time INT NOT NULL, Next_Run_Schedule_ID INT NOT NULL, Requested_to_Run INT NOT NULL, Request_Source INT NOT NULL, Request_Source_id SYSNAME COLLATE Database_Default NULL, Running INT NOT NULL, Current_Step INT NOT NULL, Current_Retry_Attempt INT NOT NULL, Job_State INT NOT NULL ) INSERT #JobResults EXECUTE master.dbo.xp_sqlagent_enum_jobs 1, ''; SELECT job.name AS [Job_Name], ( SELECT MAX(CAST( STUFF(STUFF(CAST(jh.run_date AS VARCHAR),7,0,'-'),5,0,'-') + ' ' + STUFF(STUFF(REPLACE(STR(jh.run_time,6,0),' ','0'),5,0,':'),3,0,':') AS DATETIME)) FROM msdb.dbo.sysjobs AS j INNER JOIN msdb.dbo.sysjobhistory AS jh ON jh.job_id = j.job_id AND jh.step_id = 0 WHERE j.[name] LIKE '%' + @JobName + '%' GROUP BY j.[name] ) AS [Last_Completed_DateTime], ( SELECT TOP 1 start_execution_date FROM msdb.dbo.sysjobactivity WHERE job_id = r.job_id ORDER BY start_execution_date DESC ) AS [Job_Start_DateTime], CASE WHEN r.running = 0 THEN CASE WHEN jobInfo.lASt_run_outcome = 0 THEN 'Failed' WHEN jobInfo.lASt_run_outcome = 1 THEN 'Success' WHEN jobInfo.lASt_run_outcome = 3 THEN 'Canceled' ELSE 'Unknown' END WHEN r.job_state = 0 THEN 'Success' WHEN r.job_state = 4 THEN 'Success' WHEN r.job_state = 5 THEN 'Success' WHEN r.job_state = 1 THEN 'In Progress' WHEN r.job_state = 2 THEN 'In Progress' WHEN r.job_state = 3 THEN 'In Progress' WHEN r.job_state = 7 THEN 'In Progress' ELSE 'Unknown' END AS [Run_Status_Description] FROM #JobResults AS r LEFT OUTER JOIN msdb.dbo.sysjobservers AS jobInfo ON r.job_id = jobInfo.job_id INNER JOIN msdb.dbo.sysjobs AS job ON r.job_id = job.job_id WHERE job.[enabled] = 1 AND job.name LIKE '%' + @JobName + '%' 
 ;WITH CTE_JobStatus AS ( SELECT DISTINCT NAME AS [JobName] ,s.step_id ,s.step_name ,CASE WHEN [Enabled] = 1 THEN 'Enabled' ELSE 'Disabled' END [JobStatus] ,CASE WHEN SJH.run_status = 0 THEN 'Failed' WHEN SJH.run_status = 1 THEN 'Succeeded' WHEN SJH.run_status = 2 THEN 'Retry' WHEN SJH.run_status = 3 THEN 'Cancelled' WHEN SJH.run_status = 4 THEN 'In Progress' ELSE 'Unknown' END [JobOutcome] ,CONVERT(VARCHAR(8), sjh.run_date) [RunDate] ,CONVERT(VARCHAR(8), STUFF(STUFF(CONVERT(TIMESTAMP, RIGHT('000000' + CONVERT(VARCHAR(6), sjh.run_time), 6)), 3, 0, ':'), 6, 0, ':')) RunTime ,RANK() OVER ( PARTITION BY s.step_name ORDER BY sjh.run_date DESC ,sjh.run_time DESC ) AS rn ,SJH.run_status FROM msdb..SYSJobs sj INNER JOIN msdb..SYSJobHistory sjh ON sj.job_id = sjh.job_id INNER JOIN msdb.dbo.sysjobsteps s ON sjh.job_id = s.job_id AND sjh.step_id = s.step_id WHERE (sj.NAME LIKE 'JOB NAME') AND sjh.run_date = CONVERT(CHAR, getdate(), 112) ) SELECT * FROM CTE_JobStatus WHERE rn = 1 AND run_status NOT IN (1,4) 

Я столкнулся с проблемами на одном из моих серверов, запрашивающих таблицы MSDB (так называемый код, приведенный выше), поскольку одна из моих заданий будет работать, но это не так. Существует системная хранимая процедура, которая возвращает статус выполнения, но нельзя выполнить инструкцию insert exec без ошибки. Внутри это еще одна системная хранимая процедура, которая может использоваться с инструкцией оператора insert.

 INSERT INTO #Job EXEC master.dbo.xp_sqlagent_enum_jobs 1,dbo 

И таблицу, чтобы загрузить ее в:

 CREATE TABLE #Job (job_id UNIQUEIDENTIFIER NOT NULL, last_run_date INT NOT NULL, last_run_time INT NOT NULL, next_run_date INT NOT NULL, next_run_time INT NOT NULL, next_run_schedule_id INT NOT NULL, requested_to_run INT NOT NULL, -- BOOL request_source INT NOT NULL, request_source_id sysname COLLATE database_default NULL, running INT NOT NULL, -- BOOL current_step INT NOT NULL, current_retry_attempt INT NOT NULL, job_state INT NOT NULL) 
 SELECT sj.name FROM msdb..sysjobactivity aj JOIN msdb..sysjobs sj on sj.job_id = aj.job_id WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running AND aj.start_execution_date IS NOT NULL -- job is currently running AND sj.name = '<your Job Name>' AND NOT EXISTS( -- make sure this is the most recent run select 1 from msdb..sysjobactivity new where new.job_id = aj.job_id and new.start_execution_date > aj.start_execution_date ) ) print 'running' 

Это покажет статус / время последнего прогона или если он запущен, он отображает текущее время выполнения, номер шага / информацию и SPID (если он связан с SPID). Он также показывает включенную / отключенную и работу пользователя, где он преобразуется в формат NT SID для неразрешенных учетных записей пользователей.

 CREATE TABLE #list_running_SQL_jobs (job_id UNIQUEIDENTIFIER NOT NULL, last_run_date INT NOT NULL, last_run_time INT NOT NULL, next_run_date INT NOT NULL, next_run_time INT NOT NULL, next_run_schedule_id INT NOT NULL, requested_to_run INT NOT NULL, request_source INT NOT NULL, request_source_id sysname NULL, running INT NOT NULL, current_step INT NOT NULL, current_retry_attempt INT NOT NULL, job_state INT NOT NULL) declare @sqluser nvarchar(128), @is_sysadmin INT select @is_sysadmin = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0) DECLARE read_sysjobs_for_running CURSOR FOR SELECT distinct SUSER_SNAME(owner_sid) FROM msdb.dbo.sysjobs OPEN read_sysjobs_for_running FETCH NEXT FROM read_sysjobs_for_running into @sqluser WHILE @@FETCH_STATUS = 0 BEGIN INSERT INTO #list_running_SQL_jobs EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @sqluser FETCH NEXT FROM read_sysjobs_for_running into @sqluser END CLOSE read_sysjobs_for_running DEALLOCATE read_sysjobs_for_running select j.name , 'Enbld'=CASE j.enabled WHEN 0 THEN 'no' ELSE 'YES' END , '#Min'=datediff(minute,a.start_execution_date,isnull(a.stop_execution_date,getdate())) , 'Status'=CASE WHEN a.start_execution_date is not null and a.stop_execution_date is null THEN 'Executing' WHEN h.run_status=0 THEN 'FAILED' WHEN h.run_status=2 THEN 'Retry' WHEN h.run_status=3 THEN 'Canceled' WHEN h.run_status=4 THEN 'InProg' WHEN h.run_status=1 THEN 'Success' ELSE 'Idle' END , r.current_step , spid=p.session_id , owner=isnull(suser_sname(j.owner_sid),'S-'+convert(nvarchar(12),convert(bigint,UNICODE(left(convert(nvarchar(256),j.owner_sid),1)))-convert(bigint,256)*convert(bigint,UNICODE(left(convert(nvarchar(256),j.owner_sid),1))/256)) +'-'+convert(nvarchar(12),UNICODE(right(left(convert(nvarchar(256),j.owner_sid),4),1))/256+convert(bigint,nullif(UNICODE(left(convert(nvarchar(256),j.owner_sid),1))/256,0))-convert(bigint,UNICODE(left(convert(nvarchar(256),j.owner_sid),1))/256)) +isnull('-'+convert(nvarchar(12),convert(bigint,UNICODE(right(left(convert(nvarchar(256),j.owner_sid),5),1)))+convert(bigint,UNICODE(right(left(convert(nvarchar(256),j.owner_sid),6),1)))*convert(bigint,65536)+convert(bigint,nullif(sign(len(convert(nvarchar(256),j.owner_sid))-6),-1))*0),'') +isnull('-'+convert(nvarchar(12),convert(bigint,UNICODE(right(left(convert(nvarchar(256),j.owner_sid),7),1)))+convert(bigint,UNICODE(right(left(convert(nvarchar(256),j.owner_sid),8),1)))*convert(bigint,65536)+convert(bigint,nullif(sign(len(convert(nvarchar(256),j.owner_sid))-8),-1))*0),'') +isnull('-'+convert(nvarchar(12),convert(bigint,UNICODE(right(left(convert(nvarchar(256),j.owner_sid),9),1)))+convert(bigint,UNICODE(right(left(convert(nvarchar(256),j.owner_sid),10),1)))*convert(bigint,65536)+convert(bigint,nullif(sign(len(convert(nvarchar(256),j.owner_sid))-10),-1))*0),'') +isnull('-'+convert(nvarchar(12),convert(bigint,UNICODE(right(left(convert(nvarchar(256),j.owner_sid),11),1)))+convert(bigint,UNICODE(right(left(convert(nvarchar(256),j.owner_sid),12),1)))*convert(bigint,65536)+convert(bigint,nullif(sign(len(convert(nvarchar(256),j.owner_sid))-12),-1))*0),'') +isnull('-'+convert(nvarchar(12),convert(bigint,UNICODE(right(left(convert(nvarchar(256),j.owner_sid),13),1)))+convert(bigint,UNICODE(right(left(convert(nvarchar(256),j.owner_sid),14),1)))*convert(bigint,65536)+convert(bigint,nullif(sign(len(convert(nvarchar(256),j.owner_sid))-14),-1))*0),'') ) --SHOW as NT SID when unresolved , a.start_execution_date, a.stop_execution_date , t.subsystem , t.step_name from msdb.dbo.sysjobs j left outer join (select distinct * from #list_running_SQL_jobs) r on j.job_id=r.job_id left outer join msdb.dbo.sysjobactivity a on j.job_id=a.job_id and a.start_execution_date IS NOT NULL AND --a.stop_execution_date IS NULL and not exists (select * from msdb.dbo.sysjobactivity at where at.job_id = a.job_id and at.start_execution_date > a.start_execution_date) left outer join sys.dm_exec_sessions p on p.program_name like 'SQLAgent%0x%' and j.job_id=substring(substring(p.program_name,charindex('0x',p.program_name)+2,32),7,2)+substring(substring(p.program_name,charindex('0x',p.program_name)+2,32),5,2)+substring(substring(p.program_name,charindex('0x',p.program_name)+2,32),3,2)+substring(substring(p.program_name,charindex('0x',p.program_name)+2,32),1,2)+'-'+substring(substring(p.program_name,charindex('0x',p.program_name)+2,32),11,2)+substring(substring(p.program_name,charindex('0x',p.program_name)+2,32),9,2)+'-'+substring(substring(p.program_name,charindex('0x',p.program_name)+2,32),15,2)+substring(substring(p.program_name,charindex('0x',p.program_name)+2,32),13,2)+'-'+substring(substring(p.program_name,charindex('0x',p.program_name)+2,32),17,4)+'-'+substring(substring(p.program_name,charindex('0x',p.program_name)+2,32),21,12) left outer join msdb.dbo.sysjobhistory h on j.job_id=h.job_id and h.instance_id=a.job_history_id left outer join msdb.dbo.sysjobsteps t on t.job_id=j.job_id and t.step_id=r.current_step order by 1 drop table #list_running_SQL_jobs