SQL Server Agent未启动是作业不执行的主因,需设为自动启动并配置NT Service\SQLSERVERAGENT账户;xp_cmdshell须启用且作业所有者需为sysadmin;调度受本地时区影响,跨午夜易出错;邮件通知需单独配置operator且域名须匹配。

SQL Server Agent 服务没启动,定时作业根本不会跑
SQL Server Agent 是 Windows 服务,不是 SQL Server 数据库引擎的一部分。装完 SQL Server 默认不自动启动它,更不会设为开机自启——这是绝大多数“作业不执行”的根源。
实操建议:
- 打开
services.msc,找到SQL Server Agent (MSSQLSERVER)(或带实例名的变体,如SQL Server Agent (SQLEXPRESS)) - 右键 → “属性” → “启动类型”设为
自动,然后点“启动” - 如果启动失败,常见原因是登录账户权限不足:在“登录”选项卡里,把“此账户”改成
NT Service\SQLSERVERAGENT(推荐)或一个有足够权限的域/本地账户 - 改完重启服务,再进 SSMS 看
SQL Server Agent节点是否变成绿色小箭头
作业步骤里 exec xp_cmdshell 失败:权限和配置双关卡
想用作业调外部命令(比如备份后发邮件、压缩文件),常写 EXEC xp_cmdshell 'xxx',但默认禁用,且代理账户没权限时直接报错 Msg 15281, Level 16。
实操建议:
- 先启用外围配置:
sp_configure 'show advanced options', 1; RECONFIGURE; sp_configure 'xp_cmdshell', 1; RECONFIGURE; - 确认作业所有者(Owner)是
sysadmin角色成员;否则即使启用xp_cmdshell,非 sa 用户运行的作业仍被拦截 - 避免用
sa当作业所有者——改用一个专用账号,并只授予sysadmin权限(不要给它登录 SQL Server 的能力) - 如果脚本依赖环境变量或当前路径,
xp_cmdshell启动的是全新会话,得显式cd或用绝对路径
作业调度时间不准:注意 SQL Server Agent 的时区和夏令时逻辑
SQL Server Agent 内部全部按服务器本地时区解析时间,不读取 Windows 的“自动调整夏令时”设置。一旦系统时间因夏令时切换,你设的“每天 2:00 执行”可能某天跳成 1:00 或 3:00,甚至跳过一次。
实操建议:
- 检查服务器 BIOS 时间是否准确,Windows 时间服务是否同步可靠(
w32tm /query /status) - 避免跨午夜调度(比如 23:50 → 00:10),Agent 在时钟回拨/前进时容易丢触发
- 若业务强依赖 UTC 时间,别靠 Agent 调度,改用外部调度器(如 Windows Task Scheduler +
sqlcmd)来绕过时区问题 - 用 T-SQL 查最近作业历史:
SELECT * FROM msdb.dbo.sysjobhistory WHERE step_id = 0 ORDER BY run_date DESC, run_time DESC,看run_date/run_time字段是否符合预期
邮件通知总收不到:Database Mail 和作业警报不是一回事
很多人以为配好 Database Mail 就能收到作业失败提醒,结果发现作业挂了也没邮件——因为“邮件通知”必须在作业属性里单独开启,且依赖 msdb.dbo.sp_notify_operator 这类系统过程,不是开 Database Mail 就自动生效。
实操建议:
- 先确保 Database Mail 测试通过(SSMS → “管理” → “Database Mail” → 右键“发送测试电子邮件”)
- 在作业属性 → “通知”页,勾选“当作业完成时通知”,再选“电子邮件”,并指定 operator(需提前在
msdb里建好) - operator 的邮箱地址必须和 Database Mail 配置里的“发件人地址”域名一致,否则某些 SMTP 服务器拒信
- 作业失败通知默认只发一次;如果想每次失败都发,得在“通知”页勾选“当作业失败时重复通知”,并设间隔(单位分钟)
Agent 的日志细节藏得深,sysjobhistory 表里 message 字段经常比 SSMS GUI 显示的更全;遇到“执行成功但结果不对”,一定去翻它。










