Задания агента SQL Server выполняются, даже если я отключил расписание в скрипте

#sql-server #sql-server-2012 #sql-agent-job #sql-agent

#sql-сервер #sql-server-2012 #sql-agent-job #sql-agent

Вопрос:

Мне нужно отключить все задания, выполняемые на сервере. Я выполнил следующий код:

    declare @t table (schedule_id int, [name] varchar(300))

   update msdb.dbo.sysschedules 
          set enabled = 0
   output inserted.schedule_id, inserted.name into @t
   from msdb.dbo.sysjobs j


   join msdb.dbo.sysjobschedules js
   on j.job_id = js.job_id
   join msdb.dbo.sysschedules s 
   on js.schedule_id = s.schedule_id
   where j.[name] not like 'DB -%' and j.[name] not like 'sys%' and j.[name] not like 'Maintenance%'

   select * from @t
  

Когда я проверяю данное задание и связанное с ним расписание либо из графического интерфейса SQL Agent, либо через SQL, я вижу, что расписание отключено. Однако задания все еще выполняются, и я могу увидеть даты следующего запуска в будущем, если я проверю msdb.dbo.sysjobschedules.

Единственное, что я видел в Интернете, предполагает, что существует фоновый поток, который необходимо обновить, чтобы принять это изменение? И для этого мне нужно запустить sp_sqlagent_refresh_job (не помогло) или перезапустить сервер.

Я могу перезапустить сервер, но мне любопытно, видел ли кто-нибудь еще это поведение, знает причину, знает, как это исправить другим способом.

Ответ №1:

Почему вы беспокоитесь о расписаниях? Используйте sp_update_job с динамическим SQL, чтобы отключить все задания:

 DECLARE @sql nvarchar(max)

;WITH cte AS (
SELECT  j.job_id,
        j.[name]
FROM msdb.dbo.sysjobs j
WHERE j.[name] not like 'DB -%' 
    and j.[name] not like 'sys%' 
    and j.[name] not like 'Maintenance%'
)

SELECT @sql = (
    SELECT 'EXEC msdb.dbo.sp_update_job @job_id = ''' CAST(job_id as nvarchar(max)) ''', @enabled = 0;' CHAR(10)
    FROM cte
    FOR XML PATH('')
)

EXEC sp_executesql @sql
  

Если вы PRINT @sql раньше EXEC увидите сгенерированный запрос:

 EXEC msdb.dbo.sp_update_job @job_id = 'CCCF8FC0-FCD4-4260-9A48-518AF5826297', @enabled = 0;
EXEC msdb.dbo.sp_update_job @job_id = '48BB41E6-6BEC-452B-8D42-760AECDBB808', @enabled = 0;
  

Если вам нужно остановить задания, используйте sp_stop_job.

Комментарии:

1. Это хорошее решение, спасибо. В основном мне интересно, что я пропустил, из-за чего расписания продолжают выполняться. Интересно, если бы я очистил даты следующего запуска из msdb.dbo.sysjobschedules, это помогло бы?

2. Вы были на правильном пути, есть одно замечание об этой таблице: она обновляется каждые 20 минут. Поэтому, если вы отключили расписания в sysschedules, системные расписания обновятся через ~ 20 минут, поэтому вы не сможете сразу увидеть, как меняются расписания заданий.

3. И даже если вы отключите расписания, будут выполняться задания, которые были запущены ранее. Чтобы остановить их, используйте sp_stop_job.