2008-12-13 44 views

Respuesta

3

XP_SQLAGENT_ENUM_JOBS se puede utilizar pero no está documentado. Normalmente se usa para detectar trabajos de larga ejecución.

Por supuesto, también hay sp_help_jobs o una simple revisión de las tablas de historial de empleo

+1

preferiría quedarse en tierra documentado. Soy consciente de sp_help_jobs, sin embargo, es algo feo, ya que, desde mi comprensión, necesito leer el conjunto de resultados en una tabla temporal y seleccionar desde allí. Estaba buscando algo un poco más limpio, aunque esto funcionaría. –

2

realidad que tenía que hacer esto recientemente, y esto es lo que estoy pensando en implementarlo. Estoy creando un trabajo temporal a través de sp_add_job y sp_add_jobstep, y estableciendo @delete_level en 3 (siempre elimine después de la ejecución).

No estoy 100% vendido en este enfoque, como probablemente pueda deducir del título del procedimiento almacenado. Sin embargo, funciona:

CREATE PROCEDURE spWorkaround_checkJobExists 

@job_id UNIQUEIDENTIFIER 
, @thisIteration tinyint 
, @maxRecurse tinyint 

AS 

IF (@thisIteration <= @maxRecurse) 
BEGIN 
    IF EXISTS(
    select * FROM msdb.dbo.sysjobs where job_id = @job_id 
    ) 
    BEGIN 
     WAITFOR DELAY '00:00:01' 
     DECLARE @nextIteration int 
     SET @nextIteration = @thisIteration + 1 
     EXEC dbo.spWorkaround_checkJobExists @job_id, @nextIteration, @maxRecurse 
    END 
END 

Por supuesto, tendrá que poner en un cierto código para asegurarse de que hay un número máximo de veces que esto son recursivos, pero se entiende la idea. También puede pasar un parámetro para controlar la frecuencia con que ocurre la recursión. En mi caso, después de diez segundos, los resultados no tienen sentido.

Lo que hago aquí podría modificarse para trabajos que no están destinados a descartarse inmediatamente después de la ejecución cambiando los criterios de selección para verificar el estado de ejecución del trabajo, por ejemplo, con sp_help_job pasando @job_name o @ job_id y @execution_status = 0.

2
sp_help_job @job_name @execution_status = 0 
2

Este article describe un SP para poner en marcha un trabajo del agente SQL y esperar.

-- output from stored procedure xp_sqlagent_enum_jobs is captured in the following table 
    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) 

    -- start the job 
    declare @r as int 
    exec @r = msdb..sp_start_job @job 

    -- quit if unable to start 
    if @r<>0 
     RAISERROR (N'Could not start job: %s.', 16, 2, @job) 

    -- start with an initial delay to allow the job to appear in the job list (maybe I am missing something ?) 
    WAITFOR DELAY '0:0:01'; 
    set @seccount = 1 

    -- check job run state 
    insert into @xp_results 
    execute master.dbo.xp_sqlagent_enum_jobs 1, @job_owner, @job_id 

    set @running= (SELECT top 1 running from @xp_results) 

    while @running<>0 
    begin 
     WAITFOR DELAY '0:0:01'; 
     set @seccount = @seccount + 1 

     delete from @xp_results 

     insert into @xp_results 
     execute master.dbo.xp_sqlagent_enum_jobs 1, @job_owner, @job_id 

     set @running= (SELECT top 1 running from @xp_results) 
    end 

    -- result: not ok (=1) if still running 

    if @running <> 0 begin 
     -- still running 
     return 0 
    end 
    else begin 

     -- did it finish ok ? 
     set @run_status = 0 

     select @run_status=run_status 
     from msdb.dbo.sysjobhistory 
     where [email protected]_id 
      and cast(run_date as bigint) * 1000000 + run_time >= @start_job 

     if @run_status=1 
      return 1 --finished ok 
     else --error 
      RAISERROR (N'job %s did not finish successfully.', 16, 2, @job) 

    end 

    END TRY 
+0

ese artículo me ayudó, de todos modos ... – topwik

0
SELECT TOP 1 1 AS FinishedRunning 
FROM msdb..sysjobactivity aj 
JOIN msdb..sysjobs sj on sj.job_id = aj.job_id 
WHERE aj.stop_execution_date IS NOT NULL 
AND aj.start_execution_date IS NOT NULL 
AND sj.name = 'YourJobNameHere' 
AND NOT EXISTS 
(
    SELECT TOP 1 1 
    FROM msdb..sysjobactivity New 
    WHERE New.job_id = aj.job_id 
    AND new.start_execution_date > aj.start_execution_date 
) 
Cuestiones relacionadas