2012-09-03 7 views
21

Benötigt eine gespeicherte Prozedur, die einen SQL Server-Agent-Job aufruft und zurückgibt, ob der Job erfolgreich ausgeführt wurde oder nicht.SQL Server-Agent-Job von einer gespeicherten Prozedur ausführen und Job-Ergebnis zurückgeben

Bisher habe ich

CREATE PROCEDURE MonthlyData 
AS 
EXEC msdb.dbo.sp_start_job N'MonthlyData' 

WAITFOR DELAY '000:04:00' 

EXEC msdb.dbo.sp_help_jobhistory @job_name = 'MonthlyData' 
GO 

die die Arbeit beginnt, was ist der beste Weg zurück zu bekommen, wenn der Auftrag erfolgreich oder nicht lief?

Ok hat eine Bearbeitung gemacht und WAITFOR DELAY benutzt, da der Job normalerweise zwischen 3-4 Minuten dauert, nie länger als 4. Arbeitet der Job aber effizienter?

Antwort

19

Sie können die Abfrage ausführen:

EXEC msdb.dbo.sp_help_jobhistory 
    @job_name = N'MonthlyData' 

Es wird eine Spalte run_status zurück. Stati sind:

0 - Failed 
1 - Succeeded 
2 - Retry 
3 - Canceled   

Weitere Informationen über MSDN

EDIT: Vielleicht möchten Sie zu Ihrem Job abzufragen und stellen Sie sicher, dass es ausgeführt wird. Sie können diese Informationen von der sp_help_job-Prozedur abrufen. Wenn diese Prozedur den Status 4 zurückgibt, bedeutet dies, dass der Job inaktiv ist. Dann ist es sicher, den Laufstatus zu überprüfen.

können Sie abfragen folgenden Code:

DECLARE @job_status INT 
SELECT @job_status = current_execution_status FROM OPENROWSET('SQLNCLI', 'Server=.;Trusted_Connection=yes;','exec msdb.dbo.sp_help_job @job_name = ''NightlyBackups''') 

WHILE @job_status <> 4 
BEGIN 
    WAITFOR DELAY '00:00:03' 
    SELECT @job_status = current_execution_status FROM OPENROWSET('SQLNCLI', 'Server=.;Trusted_Connection=yes;','exec msdb.dbo.sp_help_job @job_name = ''NightlyBackups''') 
END 

EXEC msdb.dbo.sp_help_jobhistory 
    @job_name = N'NightlyBackups' ; 
GO 

Dieser Code wird für den Status überprüfen, 3 Sekunden warten und erneut versuchen. Sobald wir den Status 4 erreicht haben, wissen wir, dass der Job erledigt ist und es sicher ist, nach dem Job-Verlauf zu suchen.

+1

Sie können angeben, dass Sie im Grunde abfragen müssen, bis der betreffende Job einen der "Endstatus" erreicht hat. –

+0

Also, sobald ich den Job beginne, muss ich dann abfragen, bis der Job beendet ist, dann die Jobhistory ausführen? – DtotheG

+0

@ChristianK Können Sie uns etwas mehr über das Stellen von Job Agent sagen? – testing

19

Für alle Jungs, die sind nicht benutzen dürfen die OPENROWSET Befehl, könnte dies helfen. Ich fand den Start für meine Lösung hier:

http://social.msdn.microsoft.com/Forums/en-US/89659729-fea8-4df0-8057-79e0a437b658/dynamically-checking-job-status-with-tsql

Dies beruht auf der Tatsache, dass einige Spalten der msdb.dbo.sysjobactivity Tabelle zuerst besiedelt erhalten, nachdem der Auftrag in dem einem oder dem anderen beendet.

-- Start job 
DECLARE @job_name NVARCHAR(MAX) = 'JobName' 
EXEC msdb.dbo.sp_start_job @job_name = @job_name 


-- Wait for job to finish 
DECLARE @job_history_id AS INT = NULL 

WHILE @time_constraint = @ok 
BEGIN 
    SELECT TOP 1 @job_history_id = activity.job_history_id 
    FROM msdb.dbo.sysjobs jobs 
    INNER JOIN msdb.dbo.sysjobactivity activity ON activity.job_id = jobs.job_id 
    WHERE jobs.name = @job_name 
    ORDER BY activity.start_execution_date DESC 

    IF @job_history_id IS NULL 
    BEGIN 
     WAITFOR DELAY '00:00:10' 
     CONTINUE 
    END 
    ELSE 
     BREAK 
END 


-- Check exit code 
SELECT history.run_status 
FROM msdb.dbo.sysjobhistory history 
WHERE history.instance_id = @job_history_id 

Sie können einige Überprüfungen vornehmen, wie lange die WHILE-Schleife ausgeführt werden darf. Ich entschied mich, diesen Teil aus dem Beispiel herauszuhalten.

Microsoft Führung für Exit-Codes etc .: http://technet.microsoft.com/en-us/library/ms174997.aspx

0

ich vielleicht ein bisschen spät, aber ich fand, dass die folgende Abfrage für mich gearbeitet. Es gibt die Ausführungszeit und die Ausführungsendzeit. Sie können es ändern, um auch Status zu erhalten.

SELECT 
    job.name, 
    job.job_id, 
    job.originating_server, 
    activity.run_requested_date, 
    activity.stop_execution_date, 
    DATEDIFF(SECOND, activity.run_requested_date, activity.stop_execution_date) 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 
AND job.name = @JobName