2008-12-13 7 views

Répondre

3

XP_SQLAGENT_ENUM_JOBS peut être utilisé mais il n'est pas documenté. Il est normalement utilisé pour détecter les tâches longues.

Bien sûr, il y a aussi sp_help_jobs ou simplement surveiller les tables d'historique d'emploi

+1

Je préfère rester dans la terre documentée. Je suis au courant de sp_help_jobs, mais c'est un peu moche, car, d'après ce que j'ai compris, je dois lire le jeu de résultats dans une table temporaire, puis en choisir un. Je cherchais quelque chose d'un peu plus propre, bien que cela fonctionne. –

2

J'ai dû le faire récemment, ce qui est la façon dont je pense à sa mise en œuvre. Je crée un travail temporaire via sp_add_job et sp_add_jobstep, et en définissant @delete_level sur 3 (toujours supprimer après l'exécution).

Je ne suis pas 100% vendu sur cette approche, comme vous pouvez probablement le deviner d'après le titre de la procédure stockée. Cependant, il fonctionne:

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 

Bien sûr, vous aurez envie de mettre dans un certain code pour assurer qu'il ya un nombre maximum de fois cela RECURSE, mais vous voyez l'idée. Vous pouvez également passer un paramètre pour contrôler la fréquence de la récursion. Dans mon cas, après dix secondes, les résultats sont dénués de sens. Ce que je fais ici pourrait être modifié pour les tâches qui ne sont pas destinées à être supprimées immédiatement après l'exécution en changeant les critères de sélection pour vérifier l'état d'exécution du travail, par exemple, avec sp_help_job en passant @job_name ou @ job_id et @execution_status = 0.

2
sp_help_job @job_name @execution_status = 0 
2

Cette article décrit un SP pour lancer un travail d'agent sql et attendre.

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

cet article m'a aidé, de toute façon ... – 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 
) 
Questions connexes