wake-up-neo.com

Wie kann ich den Status eines Jobs ermitteln?

Ich habe eine gespeicherte Prozedur, die einen Job einstellt. Dieser Job dauert sehr lange (ca. 30 bis 40 Minuten). Ich muss den Status dieses Jobs kennenlernen. Die folgenden Angaben würden mir helfen

1) Anzeigen der Liste aller Jobs, die für einen späteren Zeitpunkt geplant wurden und noch beginnen sollen

2) Anzeigen der Liste der laufenden Jobs und der Zeitspanne ab dem Zeitpunkt, zu dem sie ausgeführt werden

3) So können Sie feststellen, ob der Job aufgrund eines Fehlers erfolgreich abgeschlossen wurde oder zwischenzeitlich angehalten wurde.

42
Vinod

Sie können versuchen, die im System gespeicherte Prozedur sp_help_job zu verwenden. Dadurch werden Informationen zu dem Job, seinen Schritten, Zeitplänen und Servern zurückgegeben. Zum Beispiel

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

SQL Books Online sollte viele Informationen über die zurückgegebenen Datensätze enthalten.

Um Informationen zu mehreren Jobs zurückzugeben, können Sie versuchen, die folgenden Systemtabellen abzufragen, die die verschiedenen Informationen zum Job enthalten

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

Ihre Namen sind ziemlich selbsterklärend (abgesehen von SysJobServers, die Informationen darüber enthalten, wann der Job zuletzt ausgeführt wurde und das Ergebnis).

Wieder finden Sie Informationen zu den Feldern bei MSDN. Schauen Sie sich beispielsweise die Seite für SysJobs an.

44
Tim C

Ich möchte darauf hinweisen, dass keine der T-SQL-Dateien auf dieser Seite genau funktionieren wird, da keine von ihnen an der Tabelle syssessions teilnimmt, um nur die aktuelle Sitzung abzurufen und daher falsch positive Ergebnisse enthalten kann.

Sehen Sie sich dies als Referenz an: Was bedeutet es, Jobs mit einem Nullstoppdatum zu haben?

Sie können dies auch überprüfen, indem Sie die Prozedur sp_help_jobactivity in msdb analysieren.

Mir ist klar, dass dies eine alte Nachricht zu SO ist, aber ich fand diese Nachricht wegen des Problems nur bedingt hilfreich. 

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
74
efesar

Dies ist, was ich verwende, um die laufenden Jobs zu bekommen (hauptsächlich, damit ich die erledigen kann, die wahrscheinlich aufgehängt haben):

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

Wie bereits erwähnt, ist die MSDN/BOL-Dokumentation für den Inhalt der sysjobsX-Tabellen einigermaßen gut. Denken Sie daran, dass es sich um Tabellen in MSDB handelt.

27
piers7
-- 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.'
10

wir können die Msdb auf viele Arten abfragen, um die Details zu erhalten.

wenige sind

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

Dies ist eine alte Frage, aber ich hatte gerade eine ähnliche Situation, in der ich den Status von Jobs auf SQL Server überprüfen musste. Viele Leute erwähnten die sysjobactivity-Tabelle und verwiesen auf die MSDN-Dokumentation, die großartig ist. Ich möchte jedoch auch den Job-Aktivitätsmonitor hervorheben, der den Status aller auf Ihrem Server definierten Jobs enthält.

2
Gojito

Sie haben nicht angegeben, wie Sie diese Details anzeigen möchten.

Für den ersten Blick würde ich vorschlagen, Server Management Studio zu überprüfen.

Sie können die Jobs und aktuellen Status im Abschnitt SQL Server-Agent unter Jobs anzeigen. Wenn Sie einen Job auswählen, wird auf der Eigenschaftsseite ein Link zum Jobverlauf angezeigt, in dem Sie die Start- und Endzeit, eventuelle Fehler, den fehlerhaften Schritt usw. sehen können.

Sie können Warnungen und Benachrichtigungen angeben, um Sie per E-Mail zu benachrichtigen oder eine Seite aufzurufen, wenn der Job erfolgreich abgeschlossen wurde oder fehlgeschlagen ist.

Es gibt einen Job Activity Monitor, aber eigentlich habe ich ihn nie benutzt. Sie können es versuchen.

Wenn Sie es über T-SQL überprüfen möchten, weiß ich nicht, wie Sie das erreichen können.

2
Biri

Hier wird der Status/die Zeit des letzten Laufs angezeigt. Wenn er läuft, werden die aktuelle Laufzeit, die Schrittnummer/-info und die SPID (falls zugeordnete SPID) angezeigt. Außerdem werden aktivierte/deaktivierte und Jobbenutzer angezeigt, bei denen die Konvertierung für nicht aufgelöste Benutzerkonten in das NT-SID-Format erfolgt. 

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;
1
John Merager

Die oben genannten Aufgaben funktionieren, aber ich habe viele Datensätze in der Datei msdb.dbo.sys.sjob gesehenwobei run_Requested_date nicht null ist Und stop_execution_date null ---- und der Job derzeit nicht ausgeführt wird . 

Ich würde empfehlen, das folgende Skript auszuführen, um alle falschen Einträge zu löschen (stellen Sie sicher, dass zu der Zeit keine Jobs ausgeführt werden).

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  
1
Robert Sawyer

Der einfachste Weg, den ich gefunden habe, war das Erstellen einer gespeicherten Prozedur. Geben Sie den 'JobName' ein und klicken Sie auf "Los".

/*-----------------------------------------------------------------------------------------------------------

    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 + '%'
0
user2661347
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'
0

Ich hatte Probleme mit einem meiner Server, die MSDB-Tabellen abfragten (auch Code genannt), da einer meiner Jobs ausgeführt werden würde, was aber nicht der Fall war. Es gibt eine gespeicherte Systemprozedur, die den Ausführungsstatus zurückgibt. Eine Exec-Anweisung zum Einfügen kann jedoch nicht ohne Fehler ausgeführt werden. Darin befindet sich eine andere gespeicherte Systemprozedur, die mit einer Insert-Exec-Anweisung verwendet werden kann.

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

Und den Tisch zum Laden in:

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