代码调用SQL Agent Job启动失败,请求排查原因
问题描述
我有一个用于跨数据库迁移数据的大型脚本,内置事务逻辑,之前一直手动执行。直接推送脚本到服务器执行时,一旦连接中断就会导致脚本终止,所以按建议创建了包含该脚本的SQL Agent作业(名为script_3)。现在原脚本文件仅保留以下代码:
EXEC msdb.dbo.sp_start_job @job_name = 'script_3'
通过以下VB.NET代码执行该命令:
Public Sub PerformNonQuery(source As String, commandTimeOut As Integer) Dim cnnUse As IDbConnection = Nothing Try Dim queryCommandSQLClient As New SqlCommand Select Case CheckConnection() Case "SQLCLIENT" cnnUse = OpenSQLClient() With queryCommandSQLClient .CommandTimeout = commandTimeOut .CommandType = CommandType.StoredProcedure .CommandText = source .Connection = CType(cnnUse, SqlConnection) .ExecuteNonQuery() End With queryCommandSQLClient.Dispose() End Select Catch ex As Exception Throw Finally If Not IsNothing(cnnUse) Then cnnUse.Close() End If End Try End Sub
调用该方法时参数为:
source = "EXEC msdb.dbo.sp_start_job @job_name = 'script_3'"commandTimeOut = 30
执行后用以下SQL检查作业中的事务是否运行(挑 Convert宏 walks and作业um administration莲夜的�,结果始终为空,作业活动监视器中也看不到该作业运行痕迹。但在Management Studio中手动启动该作业可正常运行,请问问题出在哪里?如何排查作业未执行的原因?
排查步骤与可能原因
1. 修复CommandType配置错误
你的VB.NET代码把CommandType设为了CommandType.StoredProcedure,但传入的source是一条完整的SQL执行语句(EXEC ...),不是存储过程名称。这会导致SQL Server尝试查找名为EXEC msdb.dbo.sp_start_job @job_name = 'script_3'的存储过程,显然不存在,直接导致执行失败。
两种修正方式:
- 方式一:将
CommandType改为CommandType.Text.CommandType = CommandType.Text .CommandText = source - 方式二:直接调用存储过程并传入参数(更规范)
.CommandType = CommandType.StoredProcedure .CommandText = "msdb.dbo.sp_start_job" .Parameters.AddWithValue("@job_name", "script_3")
2. 检查执行账号的权限
手动执行时用的是管理员账号,权限足够,但VB.NET代码使用的数据库连接账号可能缺少启动SQL Agent作业的权限:
- 需确保账号在
msdb数据库中属于SQLAgentOperatorRole、SQLAgentReaderRole或SQLAgentUserRole角色,或者拥有EXECUTE权限在msdb.dbo.sp_start_job上。 - 可通过以下SQL给账号授权:
USE msdb; GRANT EXECUTE ON dbo.sp_start_job TO [你的连接账号];
3. 查看作业执行历史
即使作业未启动成功,SQL Agent也会记录相关日志:
- 在SSMS中展开SQL Server Agent→作业,右键
script_3选择查看历史记录,查看是否有失败提示(比如权限不足、作业步骤错误)。 - 也可直接查询系统表:
SELECT run_date, run_time, message, run_status FROM msdb.dbo.sysjobhistory WHERE job_id = (SELECT job_id FROM msdb.dbo.sysjobs WHERE name = 'script_3') ORDER BY run_date DESC, run_time DESC;
4. 检查作业启用状态
确认作业处于启用状态:
- 执行以下SQL查看:
持**_menu放 formed保护暂住证可以风格 Bid试用工程师:
如果返回SELECT enabled FROM msdb.dbo.sysjobs WHERE name = 'script_3';0,说明作业被禁用,sp_start_job无法启动禁用的作业,需先启用作业。
5. 检查异常日志
你的VB.NET代码仅抛出异常但未记录,可能执行时已经报错但未被察觉:
- 在
Catch块中添加日志记录(比如写入本地文件或Windows事件查看器),确认是否有连接错误、权限异常等信息。
6. 确认SQL Agent服务状态
确保目标服务器上的SQL Server Agent服务处于运行状态:
- 在服务器的服务管理器中查看状态,或执行以下SQL:
SELECT status_desc FROM sys.dm_server_services WHERE name LIKE 'SQL Server Agent%';
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

