2012-09-03 22 views
21

Necesita tener un procedimiento almacenado que llame a un trabajo del Agente SQL Server y devuelve si el trabajo se ejecutó correctamente o no.Ejecutar el trabajo del Agente SQL Server desde un procedimiento almacenado y devolver el resultado del trabajo

Hasta ahora he

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 

que se inicia el trabajo, cuál es la mejor manera de volver si el trabajo se ejecutó correctamente o no?

Ok, hice una edición y usé WAITFOR DELAY ya que el trabajo normalmente dura entre 3 y 4 minutos, nunca más de 4. ¿El trabajo pero hay una forma más eficiente de hacerlo?

Respuesta

19

Puede ejecutar la consulta:

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

Se va a devolver un run_status columna. Los estados son:

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

Más información sobre MSDN

EDITAR: Es posible que desee sondear su trabajo y asegurarse de que está ejecutada. Puede obtener esta información del procedimiento sp_help_job. Cuando este procedimiento devuelve el estado 4, significa que el trabajo está inactivo. Entonces es seguro verificar si se trata de un estado de ejecución.

puede sondear el uso siguiente código:

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 

Este código será comprobar el estado, esperar 3 segundos y vuelve a intentarlo. Una vez que obtengamos el estado de 4, sabemos que el trabajo está hecho y es seguro verificar el historial de trabajo.

+1

Es posible que desee indicar que básicamente necesita sondear, hasta que el trabajo en cuestión haya alcanzado los "estados finales". –

+0

Entonces, ¿una vez que empiezo el trabajo, necesito sondear hasta que el trabajo haya terminado y luego ejecutar la historia de trabajo? – DtotheG

+0

@ChristianK ¿Puede decirnos algo más sobre las encuestas para el agente de trabajo? – testing

19

Para todos los chicos que están No se permiten utilizar el comando OPENROWSET, esto podría ayudar. He encontrado el comienzo de mi solución aquí:

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

Esto se basa en el hecho de que algunas columnas de la tabla msdb.dbo.sysjobactivity son rellenados primera vez finalizada la tarea de un modo u otro.

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

Es posible que desee establecer algunos controles durante cuánto tiempo se permite el ciclo WHILE. Elegí mantener esa parte fuera del ejemplo.

guía de Microsoft para los códigos de salida, etc .: http://technet.microsoft.com/en-us/library/ms174997.aspx

0

que podría ser un poco tarde, pero me encontré con que la siguiente consulta trabajó para mí. Le dará tiempo de ejecución y tiempo de finalización de la ejecución. Puedes modificarlo para obtener el estado también.

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