自动启用/禁用SQL代理作业

时间:2016-12-09 19:50:12

标签: sql-server sql-agent-job

我希望能够通过确定哪个服务器是活动服务器以及哪个服务器是被动服务器来自动启用/禁用SQL代理作业。换句话说,如果启用了作业的主服务器故障转移到辅助服务器,则将禁用该作业,并且将启用辅助服务器(现在是主服务器)上的作业。

我找到了一个完全符合我需要的脚本,并根据我的标准略微修改: http://sqlmag.com/blog/alwayson-availability-groups-and-sql-server-jobs-part-28-additional-options-tackling-jobs-failo

ALTER procedure [dbo].[SQLAgentJobFailover] (@agname varchar(200))
AS
BEGIN 
   declare @is_primary_replicate bit
   declare @job_name VARCHAR(100) = 'MySQLAgentJobName'
   declare @job_enabled bit

   select @is_primary_replicate = master.dbo.fn_hadr_group_is_primary(@agname)

   declare job_cursor cursor for 
   select s.name from msdb.dbo.sysjobs s
   inner join msdb.dbo.syscategories c on s.category_id = c.category_id
   where c.name = @agname
   order by name

   open job_cursor
   fetch next from job_cursor into @job_name
   while @@fetch_status = 0
   begin
          select @job_enabled=enabled from msdb.dbo.sysjobs where name = @job_name
          if @is_primary_replicate = 1
          begin
                 if @job_enabled = 1
                       print @job_name+' enabled on primary. do nothing'
                 else 
                 begin
                       print @job_name+' disabled on primary. enable it !'
                       exec msdb.dbo.sp_update_job @job_name = @job_name,@enabled = 1
                 end
          end 
          else if (@is_primary_replicate = 0)
          begin
                 if @job_enabled = 1
                 begin
                       print @job_name+' enabled on secondary. disable it !'
                       exec msdb.dbo.sp_update_job @job_name = @job_name,@enabled = 0
                 end
                 else 
                       print @job_name+' disabled on secondary. do nothing'
          end
          fetch next from job_cursor into @job_name
   end
   close job_cursor
   deallocate job_cursor
END

GO

这里还有函数脚本:

ALTER FUNCTION dbo.fn_hadr_group_is_primary (@AGName sysname)
RETURNS bit 
AS
    BEGIN 

            DECLARE @PrimaryReplica sysname; 

            SELECT @PrimaryReplica = hags.primary_replica 
            FROM 
                    sys.dm_hadr_availability_group_states hags
                    INNER JOIN sys.availability_groups ag ON ag.group_id = hags.group_id
            WHERE
                    ag.name = @AGName;

            IF UPPER(@PrimaryReplica) =  UPPER(@@SERVERNAME)
                    RETURN 1; -- primary

            RETURN 0; -- not primary

    END; 
GO

但是,当我像这样在辅助服务器上执行时:

exec master.dbo.SQLAgentJobFailover @agname = 'CorpAnalyticsAG'

它表示命令已成功完成,但作业未被禁用。

我不知道为什么。

以下是我的AG名称

enter image description here

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

其中一个问题是您将@job_name变量设置为的值正在游标定义中被覆盖。因为它实际上没有启用或禁用作业,所以游标定义不太可能返回您实际想要在其结果集中启用或禁用的作业,这可能是由于最有可能传递的@agname值和/或光标选择定义。

因为您只想处理一个作业,所以您确实不需要游标定义,但仍需要测试主副本是否与@@SERVERNAME

相同