如何从windows应用程序调用SQL Server代理中的作业

本文关键字:代理 Server 作业 SQL 调用 windows 应用程序 | 更新日期: 2023-09-27 18:26:49

我已在SQL Server作业代理中安排了一个作业xyz。现在我想从我的windows应用程序中调用作业。

如何从windows应用程序调用SQL Server代理中的作业

调用sp_start_job

exec msdb.dbo.sp_start_job @job_name = 'YourJobName'

MSDN关于sp_start_job 的参考资料

SqlConnection DbConn = new SqlConnection(YourConnectionString);
SqlCommand ExecJob = new SqlCommand();
ExecJob.CommandType = CommandType.StoredProcedure;
ExecJob.CommandText = "msdb.dbo.sp_start_job";
ExecJob.Parameters.AddWithValue("@job_name", "YourJobName")
ExecJob.Connection = DbConn; //assign the connection to the command.
using (DbConn)
{
    DbConn.Open();
    using (ExecJob)
    {
        ExecJob.ExecuteNonQuery();
    }
}

使用sp_start_job的方法是有效的,但它遇到了一个问题,因为您不知道作业何时完成。该方法将在调用后立即返回,而不是在完成时返回。如果这对您很重要,这里有一个使用SQL Server管理对象(SMO)的函数,它只会在作业完成时返回。您需要添加对以下类的引用:

Microsoft.SqlServer.Management.Sdk.Sfc
Microsoft.SqlServer.Smo
Microsoft.SqlServer.SqlEnum 
Microsoft.SqlServer.ConnectionInfo

这是代码:

Imports System.Data.SqlClient
Imports Microsoft.SqlServer.Management.Common
Imports Microsoft.SqlServer.Management.Smo
Imports Microsoft.SqlServer.Management.Smo.Agent
public void RunSQLAgentJob(string JobName)
{
    SqlConnection DbConn = new SqlConnection(connectionstring);
    ServerConnection conn;
    Job job;
    Server server;
    using (DbConn) {
        conn = new ServerConnection(DbConn);
        server = new Server(conn);
        job = server.JobServer.Jobs(JobName);
        // make sure it's not already running before starting it
        if (job.CurrentRunStatus == JobExecutionStatus.Idle) 
            job.Start();
        while (job.CurrentRunStatus == JobExecutionStatus.Executing) {
            job.Refresh();
            Console.WriteLine($"Current status of {JobName} is {job.CurrentRunStatus.ToString}");
            System.Threading.Thread.Sleep(3000);
        }
    }
}

代理作业通常只是运行查询的脚本。是否有任何原因不能仅运行代理作业正在运行的查询?

Agent只处理调度和故障通知等。这有点过于简化,但Agent主要是一个具有运行查询的警报的调度器。尝试编写代理作业的脚本,看看它是否可以移动到由代理和应用程序运行的存储过程中。

文档描述了所有选项。如果不喜欢使用TSQL,可以使用C#或其他.NET语言中的SMO Job类。

using Microsoft.SqlServer.Management.Smo;
Server server = new Server("your_server_address");
server.JobServer.Jobs["job_name"]?.Start();

示例可在以下位置找到:https://www.craftedforeveryone.com/start-stop-manage-ms-sql-server-agent-jobs-using-c-sharp/

在您的代码中-这部分:

while (job.CurrentRunStatus == JobExecutionStatus.Executing) {
    job.Refresh();

在我的情况下,导致while循环条件没有得到满足,甚至SQL作业实际上是在前一步中启动的。将条件更改为类似以下内容不是更好吗?

 while (job.CurrentRunStatus != JobExecutionStatus.Idle)

作业可能处于多种状态(BetweenRetriesExecutingIdlePerformingCompletionActionSuspendedWaitingForStepToFinishWaitingForWorkerThread),我怀疑这就是我的原因。