it-swarm.com.de

Ausführen des SQL Server-Agentenauftrags aus einer gespeicherten Prozedur und Rückgabe des Auftragsergebnisses

Sie benötigen eine gespeicherte Prozedur, die einen SQL Server-Agent-Job aufruft und zurückgibt, ob der Job erfolgreich ausgeführt wurde oder nicht.

Soweit 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

Welches ist der beste Weg, um zurück zu kommen, wenn der Job erfolgreich ausgeführt wurde oder nicht?

Ok hat eine Bearbeitung vorgenommen und WAITFOR DELAY verwendet, da der Job normalerweise 3-4 Minuten lang nie länger als 4 dauert. Gibt es einen Job, aber gibt es einen effizienteren Weg, um ihn auszuführen?

21
DtotheG

Sie können die Abfrage ausführen:

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

Es wird eine Spalte run_status zurückgegeben. Status sind:

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

Weitere Informationen zu MSDN

EDIT: Möglicherweise möchten Sie Ihren Job abfragen und sicherstellen, dass er ausgeführt wird. Diese Informationen erhalten Sie in der Prozedur sp_help_job. Wenn diese Prozedur den Status von 4 zurückgibt, bedeutet dies, dass sich der Job im Leerlauf befindet ..__ Dann kann der Laufstatus sicher überprüft werden.

Sie können mit folgendem Code abfragen:

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 prüft den Status, wartet 3 Sekunden und versucht es erneut. Sobald wir den Status 4 erhalten haben, wissen wir, dass der Job erledigt ist und es sicher ist, den Jobverlauf zu überprüfen.

19
Fedor Hajdu

Für alle, die nicht berechtigt sind, den Befehl OPENROWSET zu verwenden, kann dies hilfreich sein. Ich habe hier den Start für meine Lösung gefunden:

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

Dies beruht auf der Tatsache, dass einige Spalten der Tabelle msdb.dbo.sysjobactivity zuerst gefüllt werden, nachdem der Job auf die eine oder andere Weise beendet wurde.

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

Möglicherweise möchten Sie prüfen, wie lange die WHILE-Schleife ausgeführt werden darf. Ich habe beschlossen, diesen Teil aus dem Beispiel herauszulassen.

Microsoft-Anleitungen für Beendigungscodes usw.: http://technet.Microsoft.com/de-de/library/ms174997.aspx

20
lapponiandevil

Hier ist ein Skript, das den Status eines Jobs überprüft und ihn ausführt, wenn er noch nicht ausgeführt wird.

declare @xp_results table (
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)

DECLARE @job_id uniqueidentifier ;
select @job_id = job_id from msdb.dbo.sysjobs where name = 'Job1';
insert into @xp_results
EXEC master.dbo.xp_sqlagent_enum_jobs 1, sa, @job_id

select case when running = 1 then 'Currently Running' else '' end as running, 
case job_state 
    when 0 then 'Not Idle or Suspended'
    when 1 then 'Executing Job'
    when 2 then 'Waiting For Thread'
    when 3 then 'Between Retries'
    when 4 then 'Idle'
    when 5 then 'Suspended'
    when 6 then 'WaitingForStepToFinish'
    when 7 then 'PerformingCompletionActions'
end as job_state
from @xp_results

IF (select running from @xp_results) <> 1
    EXEC msdb.dbo.sp_start_job 'Job1'
0
Igor Krupitsky

Ich bin vielleicht etwas spät dran, aber ich habe festgestellt, dass die folgende Abfrage für mich funktioniert hat. Es gibt Ausführungszeit und Ausführungsendezeit. Sie können es auch ändern, um den 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
0
Gericke