Задание агента SQL - выполнить как очередь - PullRequest
0 голосов
/ 28 октября 2009

У меня есть задание на SQL Server, которое вызывает 10 других заданий, используя sp_start_job. Задание состоит из 10 шагов, каждый шаг снова вызывает подзадачи.

Когда я выполняю основное задание, я вижу, что оно началось с шага 1, и через несколько секунд отображается «Закончено успешно».

Но выполнение заданий занимает много времени, и когда я проверяю информацию журнала, он показывает, что все 10 шагов выполняются одновременно, пока не завершится через несколько часов.

Мое требование состоит в том, чтобы сначала завершить шаг 1, а только затем должен начинаться шаг 2.

Ответы [ 2 ]

1 голос
/ 28 октября 2009

На форуме Microsoft Code есть способ проверить, выполняется ли хранимая процедура. Вы можете использовать это, чтобы дождаться завершения задания:

while 1=1
    begin
    WAITFOR DELAY '000:00:10'

    if not exists (
        SELECT *
        FROM master..sysprocesses p
        JOIN msdb..sysjobs j ON 
            substring(left(j.job_id,8),7,2) + 
            substring(left(j.job_id,8),5,2) +
            substring(left(j.job_id,8),3,2) + 
            substring(left(j.job_id,8),1,2) =
            substring(p.program_name,32,8)
        WHERE j.name = 'YourJobName'
        AND program_name like 'SQLAgent - TSQL JobStep (Job %'
    )
        break
    end

Таким образом, код работает так, что он ждет 10 секунд, а затем проверяет, выполняется ли задание YourJobName. Это повторяется до тех пор, пока работа больше не выполняется. Вы можете поместить это между вызовами sp_start_job.

Сказав это, должен быть более легкий путь. Разве вы не можете хранить код для каждого из 10 заданий в хранимой процедуре? «Основное» задание может вызвать 10 хранимых процедур вместо запуска 10 заданий.

0 голосов
/ 28 октября 2009

Мой первый ответ состоял в том, что вы могли бы использовать цикл, как указано выше, но проверить таблицы истории заданий в msdb, чтобы дождаться завершения предыдущего задания:

select  sj.name as job_name
from    msdb.dbo.sysjobhistory sjh
    inner join msdb.dbo.sysjobs_view sj on sj.job_id = sjh.job_id
where   sjh.step_id = 0 --Job outcome
    and sjh.run_status = 4 --In progress

Спасибо, Андомар, за вопрос. Оказывается, sysjobhistory обновляется только после завершения первого шага. Только идиот может представить, что, если одно значение run_status равно «Выполняется», таблица должна обновляться при запуске шага! Я искал вокруг, и это кажется сложной проблемой. Где-то SQL знает, что происходит, но не очень хорошо раскрывает информацию.

Кажется, вам приходится выбирать между множеством сложного кода или использованием недокументированного хранимого процесса. Вы можете легко найти километры кодовых ответов - их несколько - по Google, для sysjobhistory. Лично я предпочитаю подход XP:

create table #xp_results(
    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 )

insert #xp_results exec master.dbo.xp_sqlagent_enum_jobs @is_sysadmin = 1, @job_owner = ''

select  sj.name
from    #xp_results xpr
    inner join msdb.dbo.sysjobs_view sj on sj.job_id = xpr.job_id
where running = 1

drop table #xp_results

Я проверил это, и это действительно работает. Возможно, рискованно использовать этот XP, но это то, что использует Job Activity Monitor - я запустил его с включенным Profiler - поэтому, если он изменится, они, вероятно, предоставят какой-то другой способ найти эту информацию. Пока вы заключаете этот код в функцию или процедуру и документируете, что вы зависимы от него, мне кажется, что это наименьшее из многих зол.

...