我在SQL Server Job Agent中安排了一个xyz
的工作。现在我想从我的Windows应用程序中调用该工作。
我在SQL Server Job Agent中安排了一个xyz
的工作。现在我想从我的Windows应用程序中调用该工作。
调用 sp_start_job
函数。
exec msdb.dbo.sp_start_job @job_name = 'YourJobName'
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 Management Objects(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);
}
}
}
代理作业通常只是运行查询的脚本。您不能仅运行代理作业正在运行的查询吗?
代理只处理调度和故障通知等操作。这有点过于简单化,但代理大多是一个带有警报的调度程序,用于运行查询。尝试将代理作业编写为脚本,并查看是否可以将其移动到存储过程中,由代理和应用程序同时运行。
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)
作业可能处于许多状态之一(BetweenRetries
、Executing
、Idle
、PerformingCompletionAction
、Suspended
、WaitingForStepToFinish
、WaitingForWorkerThread
),我怀疑这就是我的情况。