Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

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

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

Электронная книга по электронной почте должна содержать много информации о возвращаемых им записях.

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

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

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

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

Ответ 2

Я хотел бы указать, что ни один из 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

Ответ 3

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

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.

Ответ 4

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

Ответ 5

мы можем запросить 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%'

Ответ 6

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

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

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

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

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

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

Ответ 7

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

Ответ 8

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

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

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  

Ответ 9

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

Ответ 10

Самый простой способ, который я нашел, - создать хранимую процедуру. Введите "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 + '%'

Ответ 11

;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)

Ответ 12

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

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) 

Ответ 13

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'

Ответ 14

Это покажет статус/время последнего запуска или, если он запущен, отображает текущее время выполнения, номер шага /info и 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