You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL代理作业调度执行时无法触发依赖作业问题咨询

问题描述

我创建了名为Test_Monitor Job的SQL代理作业:

  • 步骤1:检查ANOTHER_JOB是否已完成步骤1,若已完成则调用存储过程sp_start_job触发Test Steps Email completion作业;
  • 步骤2:延迟10分钟后检查Test Steps Email completion作业是否已启动或完成步骤1,若未满足则发送告警邮件。

手动执行Test_Monitor Job时,所有步骤均成功,Test Steps Email completion作业也能正常触发并执行。但将其设置为每日6:15自动调度执行后,该作业本身步骤显示成功,却未触发Test Steps Email completion作业,此问题在两台服务器上均出现,请问问题出在哪里?

作业代码

JOB 1: Test_Monitor Job

步骤1

BEGIN
/* SET NOCOUNT ON added to prevent extra result sets from
     interfering with SELECT statements.*/
    SET NOCOUNT ON;

/****CHECKING TO SEE IF STEP 1 OF ANOTHER JOB IS COMPLETE ****/
/* Body */
IF EXISTS( SELECT Job.name AS JobName,
       Job.enabled  AS ActiveStatus,
       JobStep.step_name AS JobStepName,
      JobStep.command AS JobCommand,
      CAST(sja.last_executed_step_date as date) lastExStepDate,
      sja.last_executed_step_id AS lastStep,
      CAST(GETDATE() AS DATE) DATE
 FROM   EDW1.msdb.dbo.sysjobs Job
       INNER JOIN SERVER.msdb.dbo.sysjobsteps JobStep  --table
           ON Job.job_id = JobStep.job_id
       JOIN SERVER.msdb.dbo.[sysjobactivity] sja 
    ON Job.job_id = sja.[job_id]
  WHERE job.name = 'ANOTHER_JOB' 
           AND CAST(sja.last_executed_step_date as date) = CAST(GETDATE() AS DATE) 
    AND sja.last_executed_step_id >1)
    
/****IF STEP 1 IS COMPLETE KICK OFF THE 'Test Steps Email completion' JOB ****/
BEGIN 
       EXEC msdb.dbo.sp_start_job @job_name = N'Test Steps Email completion';

END

/*=============
 Restore  the count notifications
--=============*/
SET NOCOUNT OFF;
END

步骤2

/**Step 2-Need to pause for the time it is to take for the job to START step 1 OF  'Test Steps 
Email completion'  ***/
WAITFOR DELAY '00:10:00.000'  

BEGIN
    /* SET NOCOUNT ON added to prevent extra result sets from
     interfering with SELECT statements.*/
    SET NOCOUNT ON;

/****CHECKING TO SEE IF STEP 1 OF 'Test Steps Email completion' IS COMPLETE OR STARTED ****/
/* Body */
IF NOT EXISTS( SELECT Job.name AS JobName,
       Job.enabled  AS ActiveStatus,
       JobStep.step_name AS JobStepName,
      JobStep.command AS JobCommand,
      CAST(sja.last_executed_step_date as date) lastExStepDate,
      sja.last_executed_step_id AS lastStep,
      CAST(GETDATE() AS DATE) DATE
 FROM   msdb.dbo.sysjobs Job
       INNER JOIN msdb.dbo.sysjobsteps JobStep  --table
           ON Job.job_id = JobStep.job_id
       JOIN msdb.dbo.[sysjobactivity] sja 
    ON Job.job_id = sja.[job_id]
  WHERE job.name =  'Test Steps Email completion' 
           AND CAST(sja.last_executed_step_date as date) = CAST(GETDATE() AS DATE) 
            AND sja.last_executed_step_id >=1)

            
/****IF STEP 1 OF  'Test Steps Email completion' IS NOT STARTED OR COMPLETE SEND EMAIL TO 
DBA'S ****/
BEGIN 
        EXEC msdb.dbo.sp_send_dbmail  
        @profile_name = 'Notifier Email Profile',  
        @recipients =  'MY_EMAIL;',
        @body = 'DBAs the Test Steps Email completion job has not started. DBAs Please log 
into Server and Manually start job Test Steps Email completion!',
        @subject = 'ALERT!! DBAs Need to Manually start Job Test Steps Email completion on 
Server  ASAP!'
;
;

END
/*=============
 Restore  the count notifications
--=============*/
SET NOCOUNT OFF;
END

JOB 2: Test Steps Email completion

步骤1

EXEC  msdb.dbo.sp_SQLNotify 
    @MailTo = 'EMAIL', 
    @Subject = 'Testing Solution for ANOTHER_JOB and Test_Monitor Job.', 
                @Priority = 'High'
问题排查及解决方向

1. 核心判断条件逻辑错误

步骤1中判断ANOTHER_JOB步骤1是否完成的条件sja.last_executed_step_id >1存在问题:

  • 如果ANOTHER_JOB的步骤1对应的step_id是1(默认第一个步骤的step_id为1),那么该步骤执行完成后,last_executed_step_id的值就是1,条件>1永远不满足,自然不会触发后续作业。
  • 手动执行时可能ANOTHER_JOB已经执行到了步骤2及以后,所以条件成立;但自动调度时ANOTHER_JOB仅完成了步骤1,导致条件不触发。

解决办法:将条件改为sja.last_executed_step_id >=1,或者根据ANOTHER_JOB的实际步骤ID调整判断值,确保步骤1完成时条件能命中。

2. 远程服务器引用权限/上下文问题

步骤1的查询中使用了EDW1.msdb.dbo.sysjobs、SERVER.msdb.dbo.sysjobsteps这类四部分名称:

  • 手动执行时,当前用户可能有访问远程服务器EDW1/SERVER的权限,且上下文正确;但自动调度的作业执行账户可能没有对应的远程登录权限,或者无法解析服务器名称,导致查询返回空结果,条件不成立。
  • 如果ANOTHER_JOB实际在本地服务器,完全不需要添加服务器前缀,直接使用msdb.dbo.sysjobs、msdb.dbo.sysjobsteps即可。

解决办法:

  • 确认ANOTHER_JOB所在服务器,若在本地则去掉查询中的服务器前缀;
  • 若确实是远程服务器,确保作业执行账户有访问远程服务器msdb库的权限(配置链接服务器并赋予对应权限)。

3. sysjobactivity表数据读取不精确

sysjobactivity表会保留多个作业活动记录,若未筛选最新的会话记录,可能读取到旧的执行数据:

  • 自动调度时,可能查询到的是之前的作业活动记录,导致日期或步骤ID判断错误。

解决办法:修改查询,加入最新会话的筛选条件,比如:

JOIN SERVER.msdb.dbo.[sysjobactivity] sja 
    ON Job.job_id = sja.[job_id]
WHERE sja.session_id = (SELECT MAX(session_id) FROM SERVER.msdb.dbo.sysjobactivity)
-- 同时保留原有其他条件

4. 作业执行账户权限不足

手动执行时使用的是当前登录用户(通常是有较高权限的DBA账户),而自动调度的作业执行账户可能权限不足:

  • 没有读取msdb.dbo.sysjobs、sysjobsteps、sysjobactivity表的权限;
  • 没有执行msdb.dbo.sp_start_job的权限。

解决办法:

  • 将作业执行账户添加到msdb库的SQLAgentOperatorRole角色中,该角色拥有管理作业的基本权限;
  • 或者单独赋予账户读取相关系统表和执行sp_start_job的权限。

5. 时间条件的边界问题

CAST(sja.last_executed_step_date as date) = CAST(GETDATE() AS DATE)的判断可能遇到边界情况:

  • 若ANOTHER_JOB的步骤1在当天0点前执行(比如跨天执行),自动调度6:15检查时日期条件不满足;但手动执行时可能是在当天执行完ANOTHER_JOB后操作,所以条件成立。

解决办法:根据ANOTHER_JOB的实际执行时间调整日期判断逻辑,比如允许检查最近24小时内的执行记录:

AND sja.last_executed_step_date >= DATEADD(DAY, -1, GETDATE())

内容的提问来源于stack exchange,提问作者Elizabeth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 21:10:20