简易动态调度器:SQL Server 调度工具

简易动态调度器是一种基于SQL Server的调度工具,它利用数据库存储所有配置和逻辑。这种调度器的主要特点包括简单易管理、动态而非静态、纯T-SQL编写、开源且轻量级。它只提供决策机制(运行或暂停),并不实际执行任何操作。

在许多情况下,可能无法使用现成的调度器,或者使用它们需要等待内部流程(如等待运维或数据库管理员)来添加、修改、删除、禁用或启用调度任务。此外,创建成百上千个调度任务或作业可能并不现实。如果调度器需要根据特定业务规则变化,那么简易动态调度器可能是一个合适的解决方案。

简易动态调度器参考了SQL Server的作业调度功能构建,它允许定义调度器的名称、类型(一次性或周期性)、频率(每日、每周、每月)、周期性(每隔X天、周、月)、运行的星期几(对于周计划)、确切的日期或月份中的工作日(对于月计划)、每天的执行次数(每天一次或多次)、调度器的保留期限(开始和结束日期)、有效/有效天(运行计划的天数)、调度器是否激活(启用或禁用)。

所有调度器的配置参数都存储在配置表中。唯一不存储在配置表中的信息是使用特定调度器的进程的上次执行时间,因为多个进程可以使用同一个调度器。因此,需要为进程单独维护这些信息。

简易动态调度器的代码非常直观,包括一个包含调度配置的表(t_SimpleDynamicScheduler),一个用于确定特定调度器是否应该运行的标量函数(f_SimpleDynamicScheduler_CheckRun),以及一个用于模拟调度运行序列的表值函数(f_SimpleDynamicScheduler_Simulate)。

调度器类型

使用简易动态调度器可以创建以下类型的调度器:

  • 一次性
  • 周期性
  • 每日
  • 每周
  • 每月
  • 确切日期
  • 确切工作日

此外,所有周期性调度器都可以有日内计划(每天多次执行)。

创建调度器

以下是使用简易动态调度器定义的五种不同类型的调度器的示例。将使用虚构的场景来解释如何通过示例创建每种类型的调度器。在场景中,将用下标标记重要词汇。稍后,将使用这些下标来解释如何将场景中的信息转换为配置表字段。

假设想要创建一个在2016年4月5日晚上10:30启动的一次性调度器。需要初始化以下字段:

  • 名称 = 一次性调度器
  • 类型 = O
  • 开始时间 = 22:30:00
  • 开始日期 = 2016-04-05
  • 启用 = 是

如果想要创建一个从2016年4月20日开始,到2016年5月31日结束,每三天运行一次,每天上午9:00启动的周期性每日调度器,将初始化以下字段:

  • 名称 = 每日周期性调度器
  • 类型 = R
  • 频率 = D
  • 每隔X天 = 3
  • 每天频率 = O
  • 开始时间 = 9:00:00
  • 开始日期 = 2016-04-20
  • 结束日期 = 2016-05-31(包含)
  • 启用 = 是

假设想要创建一个从2016年3月15日开始的周期性每周调度器,每两周在周一、周四和周五下午2:30启动一次。需要初始化以下字段:

  • 名称 = 每周周期性调度器
  • 类型 = R
  • 频率 = W
  • 每隔X周 = 2
  • 星期几 = Mo-Th-Fr
  • 每天频率 = O
  • 开始时间 = 14:30:00
  • 开始日期 = 2016-03-15
  • 启用 = 是

接下来,将创建一个在每个月的第12天启动的周期性每月调度器,每三个月运行一次,每天上午11:00启动一次,从2016年2月10日开始,仅在工作日运行:

  • 名称 = 每月日期周期性调度器
  • 类型 = R
  • 频率 = M
  • 每隔X月 = 3
  • 每月出现 = D
  • 确切日期 = 12
  • 每天频率 = O
  • 开始时间 = 11:00:00
  • 开始日期 = 2016-02-10
  • 有效天 = Mo-Tu-We-Th-Fr
  • 启用 = 是

类似于之前的调度器,如果想要创建一个在每个月的第二个星期日启动的周期性每月调度器,从2016年1月1日开始,到2016年12月31日结束,每天晚上11:45启动一次:

  • 名称 = 每月工作日周期性调度器
  • 类型 = R
  • 频率 = M
  • 每隔X月 = 1
  • 每月出现 = W
  • 确切工作日 = Su
  • 每隔X个工作日 = 2
  • 每天频率 = O
  • 开始时间 = 23:45:00
  • 开始日期 = 2016-01-01
  • 结束日期 = 2016-12-31(包含)
  • 启用 = 是

日内调度器用于希望调度器每天运行多次的情况。例如,假设希望调度器从上午9:00开始,到下午5:00结束,每两小时执行一次。需要初始化以下字段:

  • 每天频率 = E
  • 开始时间 = 9:00:00
  • 每隔X值 = 2
  • 每隔X时间单位 = H
  • 结束时间 = 17:00:00

检查调度器是否应该运行

要确定某个调度器是否应该运行,将使用名为[dbo].[f_SimpleDynamicScheduler_CheckRun]的标量函数:

SELECT [dbo].[f_SimpleDynamicScheduler_CheckRun] ( @pScheduleId, @pLastRun, @pCurrentDate )

此函数的参数包括:

  • @pScheduleId - 调度器的ID(配置表中的ID列)
  • @pLastRun - 进程/作业/活动使用此调度器的上次运行时间
  • @pCurrentDate - 当前日期和时间(通常是getdate(),留作参数以便于测试和模拟)

函数返回以下值:

  • RUN - 应该运行进程
  • HOLD - 应该暂停进程
  • 其他 - 函数有错误。返回值是错误文本

根据返回结果,应该在代码中实现逻辑以:

  • 如果需要,运行必要的代码
  • 如果进程成功完成,更新进程的LastRun值
  • 如果有任何错误,向用户显示错误

调度器模拟器

为了测试和模拟目的,提供了一个名为[dbo].[f_SimpleDynamicScheduler_Simulate]的函数。它允许通过在定义的时间段内模拟其使用来测试调度执行周期。

以下面的调度器为例:

  • ID = 3
  • 类型 = R
  • 频率 = D
  • 每隔X天 = 1
  • 每天频率 = E
  • 开始时间 = 9:00:00
  • 每隔X值 = 120
  • 每隔X时间单位 = M
  • 结束时间 = 16:30:00
  • 开始日期 = 2016-04-25
  • 结束日期 = 2016-05-13
  • 启用 = 是

要模拟这个调度器,将运行以下代码:

SELECT * FROM [dbo].[f_SimpleDynamicScheduler_Simulate] ( 3, '20160405', '20160520', 'M', 10, null )

此函数的参数表示:对于调度器3,在2016年4月5日至2016年5月20日期间,每10分钟模拟一次执行。之前的LastRun未知(NULL)。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485