如何使用 T-SQL 停止 SQL Server 代理作業計劃程序?
我有一份工作,我在協調的時間段內手動啟動,做了一堆繁重的工作(主要是恢復備份和為不同的伺服器配置)
有幾個作業計劃以分鐘到幾天的增量執行。我想“關閉”調度程序,這樣在我的手動工作完成之前,什麼都不會按計劃執行。我意識到,在調度程序重新啟動後,錯過的作業將在下一個預定時間之前不會再次執行。
- 第一步:停止調度程序
- 幾個舉重的步驟:做艱苦的工作
- 最後一步:啟動調度器
我找到了一個Oracle命令,但我是 100% Microsoft SQL Server
我知道如果我關閉 SQL 代理,作業將不會執行,但這不是我想要的。
今天存在的工作預計下次不會是相同的工作。使用EXEC dbo.sp_update_job禁用作業不是一個可行的解決方案。
**附加資訊:**可能還有一些作業由於某種原因被故意禁用,但確實希望重新啟用。停止調度程序似乎是最好的選擇。
我建議首先創建一個暫存表,該表將為您保存一些資訊。該表應構造為保存以下程式碼輸出的數據。我建議至少儲存
Schedule_ID
、name
和。job_id
(如果你想作弊,你可以展開星號並選擇你想要的列,然後INTO
在database.schema.table_name_you_want_to_create中添加單詞,它會第一次為你創建表。之後你可以更改將其放入插入中。)SELECT * FROM MSDB.dbo.sysschedules ss INNER JOIN msdb.dbo.sysjobschedules jss ON jss.schedule_id = ss.schedule_id WHERE ss.enabled = 1
該程式碼返回所有計劃的計劃,並且它還執行內部連接以將返回的數據限制為僅與目前啟用的作業配對的計劃。
然後,您可以創建一個循環或游標或類似於循環臨時表並執行sp_update_schedule 過程的東西。這將禁用所有已啟用並與作業配對的計劃。維護完成後,您可以再次執行循環,但這一次啟用您之前禁用的計劃。
如果您想要一個循環的範例,您可以查看我過去在 stack overflow 上創建的範例。
我已經回去並使用這些建議來創建完整的程式碼解決方案。請看下面,總共有兩個腳本。第一個將禁用您的作業,第二個將重新啟用它們。在將其投入生產之前,在測試環境中進行測試。 完整性的來源。
腳本一:
USE MSDB; /************************************************************* Checking for history table. Creating it if it doesn't exist. *************************************************************/ IF OBJECT_ID('dbo.JobsEnabledTracker', 'U') IS NULL BEGIN CREATE TABLE [dbo].[JobsEnabledTracker]( [Id] [INT] IDENTITY(1, 1) NOT NULL, [job_id] [UNIQUEIDENTIFIER] NULL, [schedule_id] [BIGINT] NULL, [enabled] [BIT] NULL); END; IF EXISTS ( SELECT 1 FROM [dbo].[JobsEnabledTracker] WHERE [enabled] = 1 ) OR ( SELECT COUNT(*) FROM [dbo].[JobsEnabledTracker] ) = 0 BEGIN PRINT 'There are jobs enabled or there are no jobs yet populated in the history table.'; /*********************** Clear out history table ***********************/ PRINT 'Truncating history table: dbo.JobsEnabledTracker'; TRUNCATE TABLE [dbo].[JobsEnabledTracker]; PRINT 'Inserting records into history table: dbo.JobsEnabledTracker'; /****************************** Add in values to history table ******************************/ INSERT INTO [dbo].[JobsEnabledTracker] ( [job_id], [schedule_id], [enabled] ) SELECT [jss].[job_id], [jss].[schedule_id], 1 AS 'enabled' FROM [msdb].[dbo].[sysschedules] AS [ss] INNER JOIN [msdb].[dbo].[sysjobschedules] AS [jss] ON [jss].[schedule_id] = [ss].[schedule_id] WHERE [ss].[enabled] = 1; /********************************************************************************** Table variable to hold schedules and jobs enabled. This is important for the loop. **********************************************************************************/ DECLARE @JobsEnabled TABLE ([Id] INT PRIMARY KEY IDENTITY(1, 1), [job_id] UNIQUEIDENTIFIER, [schedule_id] BIGINT, [enabled] BIT ); /***************************************** Insert schedules that we need to disable. *****************************************/ INSERT INTO @JobsEnabled ( [job_id], [schedule_id], [enabled] ) SELECT [job_id], [schedule_id], [enabled] FROM [dbo].[JobsEnabledTracker]; /******************************** Holds the job id and schedule id ********************************/ DECLARE @jobid UNIQUEIDENTIFIER; DECLARE @scheduleid BIGINT; /*********************************** Holds the ID of the row in the loop ***********************************/ DECLARE @ID INT= 0; /********************** Check if records exist **********************/ IF EXISTS ( SELECT [Id] FROM @JobsEnabled ) BEGIN PRINT 'Loop mode, jobs found enabled.'; /********** Begin loop **********/ WHILE(1 = 1) BEGIN /*************************************** Grab jobid, scheduleid, and id of rows. ***************************************/ SELECT @jobid = ( SELECT TOP 1 [job_id] FROM @JobsEnabled ORDER BY [job_id] ); SELECT @scheduleid = ( SELECT TOP 1 [schedule_id] FROM @JobsEnabled ORDER BY [job_id] ); SELECT @ID = ( SELECT TOP 1 [Id] FROM @JobsEnabled ORDER BY [job_id] ); /************************************ Re-enable schedule associated to job ************************************/ PRINT 'Disabling schedule_id: '+CAST(@scheduleid AS VARCHAR(255))+' paired to job_id: '+CAST(@jobid AS VARCHAR(255)); EXEC [sp_update_schedule] @schedule_id = @scheduleid, @enabled = 0; /********************* Removes row from loop *********************/ DELETE FROM @JobsEnabled WHERE [Id] = @ID; UPDATE [dbo].[JobsEnabledTracker] SET [enabled] = 0 WHERE [job_id] = @jobid AND [schedule_id] = @scheduleid; /**************************** No more rows, stops deleting ****************************/ IF ( SELECT COUNT(*) FROM @JobsEnabled ) <= 0 BEGIN BREAK END; /******** End Loop ********/ END; PRINT 'Exiting loop, disabling schedules paired to jobs complete.'; /********** End elseif **********/ END; ELSE BEGIN PRINT 'All done'; END; END; ELSE BEGIN PRINT 'YOU HAVE JOBS STILL DISABLED, EXITING SCRIPT. PLEASE RUN SCRIPT TWO FIRST.'; END;
腳本二
USE MSDB; /******************************************************************************* Check for history table. This physical table tells us what jobs we are going to enable the scheduler for. *******************************************************************************/ IF OBJECT_ID('dbo.JobsEnabledTracker', 'U') IS NOT NULL BEGIN IF EXISTS ( SELECT 1 FROM [dbo].[JobsEnabledTracker] WHERE [enabled] = 0 ) BEGIN PRINT 'Jobs disabled in history table: dbo.JobsEnabledTracker found.'; /********************************************************************************** Table variable to hold schedules and jobs enabled. This is important for the loop. **********************************************************************************/ DECLARE @JobsEnabled TABLE ( [Id] int PRIMARY KEY IDENTITY(1, 1) , [job_id] uniqueidentifier , [schedule_id] bigint , [enabled] bit ); /******************************************************************************* Insert schedules that we had disabled that we need to go back in and re-enable. *******************************************************************************/ INSERT INTO @JobsEnabled( [job_id], [schedule_id], [enabled] ) SELECT [job_id], [schedule_id], [enabled] FROM [dbo].[JobsEnabledTracker]; /******************************** Holds the job id and schedule id ********************************/ DECLARE @jobid uniqueidentifier; DECLARE @scheduleid bigint; /*********************************** Holds the ID of the row in the loop ***********************************/ DECLARE @ID int= 0; /********************** Check if records exist **********************/ IF EXISTS ( SELECT [Id] FROM @JobsEnabled ) BEGIN PRINT 'Loop mode, jobs found disabled.'; /********** Begin loop **********/ WHILE 1 = 1 BEGIN /*************************************** Grab jobid, scheduleid, and id of rows. ***************************************/ SELECT @jobid = ( SELECT TOP 1 [job_id] FROM @JobsEnabled ORDER BY [job_id] ); SELECT @scheduleid = ( SELECT TOP 1 [schedule_id] FROM @JobsEnabled ORDER BY [job_id] ); SELECT @ID = ( SELECT TOP 1 [Id] FROM @JobsEnabled ORDER BY [job_id] ); /*************************************** Re-enable schedule associated to job ***************************************/ PRINT 'Enabling schedule_id: '+CAST(@scheduleid AS varchar(255))+' paired to job_id: '+CAST(@jobid AS varchar(255)); EXEC [sp_update_schedule] @schedule_id = @scheduleid, @enabled = 1; /********************* Removes row from loop *********************/ DELETE FROM @JobsEnabled WHERE [Id] = @ID; /*********************** Set job back to enabled ***********************/ UPDATE [dbo].[JobsEnabledTracker] SET [enabled] = 1 WHERE [job_id] = @jobid AND [schedule_id] = @scheduleid; /**************************** No more rows, stops deleting ****************************/ IF ( SELECT COUNT(*) FROM @JobsEnabled ) <= 0 BEGIN BREAK; END; /******** End Loop ********/ END; PRINT 'Exiting loop, enabling schedules paired to jobs complete.'; /********** End elseif **********/ END; ELSE BEGIN PRINT 'All done'; END; END; ELSE BEGIN PRINT 'dbo.JobsEnabledTracker has no disabled jobs currently.'; END; END; ELSE BEGIN PRINT 'dbo.JobsEnabledTracker is NULL, you may need to run the first script to create and populate this table.'; END;