2008-12-13 5 views

ответ

3

XP_SQLAGENT_ENUM_JOBS можно использовать, но это недокументировано. Обычно он используется для обнаружения длительных рабочих заданий.

Конечно, есть также sp_help_jobs или просто мониторинг таблиц истории заданий

+1

Я предпочел бы остаться в документированной земли. Мне известно о sp_help_jobs, однако это отвратительно, так как, по моему мнению, мне нужно прочитать набор результатов в таблице temp, а затем выбрать из этого. Я искал что-то немного чище, хотя это сработало бы. – 2008-12-16 16:42:16

2

Я на самом деле должен был сделать это в последнее время, и это, как я думаю о его реализации. Я создаю временную работу через sp_add_job и sp_add_jobstep и устанавливаю @delete_level в 3 (всегда удаляем после запуска).

Я не на 100% продаю этот подход, как вы, вероятно, можете сказать из названия хранимой процедуры. Тем не менее, это не работа:

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 

Конечно, вы хотите поместить в какой-то код, чтобы убедиться, что есть максимальное количество раз это будет RECURSE, но вы получите идею. Вы также можете передать параметр, чтобы контролировать, как часто происходит рекурсия. В моем случае, через десять секунд, результаты не имеют смысла.

То, что я здесь делаю, может быть изменено для заданий, которые не должны быть немедленно удалены после выполнения, изменяя критерии выбора, чтобы проверить статус выполнения задания, например, sp_help_job, проходящий @job_name или @ job_id и @execution_status = 0.

2

Это article описывает SP начать работу агента SQL Server и ждать.

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

эта статья мне помогла, во всяком случае ... – topwik 2013-03-27 17:43:15

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 
) 
Смежные вопросы