Создайте дочерний (ищущий) пакет, а затем создайте задание агента SQL с помощью одного шага, выполняющего пакет. Тогда ваш родительский пакет может выполнить задание вместо пакета напрямую. Агент SQL позаботится о «блокировке» пакета, поскольку в задании может быть запущен только один экземпляр.
Возможно, вам потребуется встроить некоторый механизм ожидания. Вы можете запросить msdb.dbo.sysjobactivity
, чтобы определить, выполняется задание или нет.
Я недавно создал пакет, который делает почти точно то, что вы пытаетесь сделать. Вот как это выглядело в итоге:
На первом шаге «Выполнение SQL» я получаю JobId и имена шагов. Вызываемый процесс использует следующий запрос (я передаю @JobName):
SELECT @JobId = job_id
FROM msdb.dbo.sysjobs
WHERE name = @JobName
Затем Is the job running
Задача «Выполнение SQL» выполняет следующий запрос, чтобы проверить, выполняется ли задание:
DECLARE @JobId UNIQUEIDENTIFIER
SET @JobId = ?
SELECT
Running =
CASE
WHEN start_execution_date IS NOT NULL AND stop_execution_date IS NULL
THEN 1
ELSE 0
END
FROM msdb.dbo.sysjobactivity
WHERE job_id = @JobId
Я сохраняю значение в переменной, а затем включаю и отключаю соответствующие пути. Если задание выполняется, я жду 30 секунд, а затем цикл Wait while job is running
перезапускается и снова проверяет состояние активности задания.
Прошло 1 секунда ожидания, чтобы у обработчика базы данных было достаточно времени для обновления таблицы активности задания. Мой пакет терпел неудачу, потому что он выполнял проверку слишком быстро и думал, что можно начинать следующее выполнение задания. На мгновение делая паузу, мы можем получить точные результаты при проверке статуса активности работы.
Как только пакет достигает Start Job Step
, он запускает следующий запрос для запуска задания:
DECLARE @step VARCHAR(100)
,@Job VARCHAR(100)
SET @step = ?
SET @Job = ?
EXEC msdb.dbo.sp_start_job @job_id = @job, @step_name = @step
Если в вашем случае вам не нужно указывать шаг, так как в вашем задании пакета поиска будет только один шаг.