当作业发生时,我需要创建一个用于监视SQL Server 2000代理作业状态和信息的应用程序,与Windows应用程序事件日志中显示的相同。现在我已经通过连接字符串连接到数据库,但我不知道如何从Job获取状态和信息。
我需要在Textbox上显示状态和信息。
你有什么建议怎么办?
开发者工具:
我是菜鸟程序员。
答案 0 :(得分:5)
我已经可以这样做了......
我在数据库“msdb”中选择表格“Sysjobserver”,以获取我想要的工作的阅读状态,日期和时间。
使用此代码
public void GetJobsAndStatus()
{
string sqlJobQuery = "select j.job_id, j.name, j.enabled, jh.run_status," +
" js.last_outcome_message, jh.run_date, jh.step_name, jh.run_time" +
" from sysjobs j left join sysjobhistory jh on (j.job_id = jh.job_id)" +
" left join sysjobservers js on (j.job_id = js.job_id)" +
" where jh.run_date = (select Max(run_date) from sysjobhistory)" +
" and jh.run_time = (select Max(run_time) from sysjobhistory)";
// create SQL connection and set up SQL Command for query
using (SqlConnection _con = new SqlConnection("server=10.15.13.70;database=msdb;user id=sa;pwd="))
using (SqlCommand _cmd = new SqlCommand(sqlJobQuery, _con))
{
try
{
// open connection
_con.Open();
SqlConnection.ClearPool(_con);
// create SQL Data Reader and grab data
using (SqlDataReader rdr = _cmd.ExecuteReader())
{
// as long as we get information from the reader
while (rdr.Read())
{
Guid jobID = rdr.GetGuid(0); // read Job_id
string jobName = rdr.GetString(1); // read Job name
byte jobEnabled = rdr.GetByte(2); // read Job enabled flag
int jobStatus = rdr.GetInt32(3); // read last_run_outcome from sysjobserver
string jobMessage = rdr.GetString(4); // read Message from sysjobserver
int jobRunDate = rdr.GetInt32(5); // read run_date from sysjobhistory
string jobStepName = rdr.GetString(6); // read StepName from sysjobhistory
int jobRunTime = rdr.GetInt32(7); // read run_time from sysjobhistory
String[] lviData = new String[] // ตัวแปรอะเรย์ชื่อ lviData
{
jobID.ToString(),
jobName.ToString(),
jobStepName.ToString(),
jobMessage.ToString(),
jobStatus.ToString(),
jobRunDate.ToString(),
jobRunTime.ToString(),
//jobEnabled.ToString(),
};
newData = lviData;
DisplayList(); // for display data on datagridview
}
rdr.Close();
}
}
非常感谢大家的帮助。 :-D
答案 1 :(得分:3)
查询的SQL存储过程不会为您提供任何系统数据,除非您在msdb系统数据库上拥有db_owner权限,至少在SQL Server 2008中。因此,所提到的方法通常不适用于您要显示的应用程序或管理工作。但是,SMO命名空间为您提供了许多SQL Server管理功能的托管代码解决方案,包括SQL Server代理函数,这些函数只需要您通常可以为应用程序用户排序的SQLServerAgent *权限。这里给出了使用SMO类来处理作业的一个很好的介绍:
http://www.codeproject.com/Tips/367470/Manage-SQL-Server-Agent-Jobs-using-Csharp
我现在正在处理类似的任务,而SQL查询让我拒绝访问,使用C#代码和Microsoft.SqlServer.Management.Smo.Agent命名空间我刚刚使用此代码列出了所有作业:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo.Agent;
namespace SmoTest
{
class Program
{
static readonly string SqlServer = @"SQL01\SQL01";
static void Main(string[] args)
{
ServerConnection conn = new ServerConnection(SqlServer);
Server server = new Server(conn);
JobCollection jobs = server.JobServer.Jobs;
foreach (Job job in jobs)
{
Console.WriteLine(job.Name);
}
}
}
}
答案 2 :(得分:2)
这应该是一个很好的起点,了解如何使用T-SQL查找SQL代理作业:
View (and disable) SQL Agent Jobs with TSQL
该脚本将列出您数据库中的所有作业,以及下次运行它们的时间等等。
使用job_name,您还应该能够使用服务器上msdb
数据库中的SQL Server Agent Stored Procedures找到有关您的工作的详细信息。
答案 3 :(得分:1)
在 SQL Server 2005及更高版本上,您可以使用系统存储过程msdb.dbo.sp_help_job获取有关SQL Server代理作业的信息,包括状态。您可以在http://msdn.microsoft.com/en-us/library/ms186722(v=SQL.90).aspx了解有关sp_help_job的更多信息。
以下是使用C#执行此操作的示例代码。
private Dictionary<int, string> ExecutionStatusDictionary = new Dictionary<int, string>()
{
{0, "Not idle or suspended"},
{1, "Executing"},
{2, "Waiting for thread"},
{3, "Between retries"},
{4, "Idle"},
{5, "Suspended"},
{7, "Performing completion actions"}
};
public string GetStatus()
{
SqlConnection msdbConnection = new SqlConnection("Data Source=SERVERNAME;Initial Catalog=msdb;Integrated Security=SSPI");
System.Text.StringBuilder resultBuilder = new System.Text.StringBuilder();
try
{
msdbConnection.Open();
SqlCommand jobStatusCommand = msdbConnection.CreateCommand();
jobStatusCommand.CommandType = CommandType.StoredProcedure;
jobStatusCommand.CommandText = "sp_help_job";
SqlParameter jobName = jobStatusCommand.Parameters.Add("@job_name", SqlDbType.VarChar);
jobName.Direction = ParameterDirection.Input;
jobName.Value = "LoadRegions";
SqlParameter jobAspect = jobStatusCommand.Parameters.Add("@job_aspect", SqlDbType.VarChar);
jobAspect.Direction = ParameterDirection.Input;
jobAspect.Value = "JOB";
SqlDataReader jobStatusReader = jobStatusCommand.ExecuteReader();
while (jobStatusReader.Read())
{
resultBuilder.Append(string.Format("{0} {1}",
jobStatusReader["name"].ToString(),
ExecutionStatusDictionary[(int)jobStatusReader["current_execution_status"]]
));
}
jobStatusReader.Close();
}
finally
{
msdbConnection.Close();
}
return resultBuilder.ToString();
}
答案 4 :(得分:0)
您可以使用此SELECT获取所有服务器作业的列表:
SELECT [name] FROM msdb.dbo.sysjobs
如果您想获得当前正在运行的作业及其信息的列表,我建议您在应用程序调用的SQL中编写存储过程。这里有一个很好的演示,你可以使用......
http://feodorgeorgiev.com/blog/2010/03/how-to-query-currently-running-sql-server-agent-jobs/
祝你好运!答案 5 :(得分:0)
对于我的用例,我特别需要知道作业何时完成运行以及它是否成功。这是我的代码:
using System;
using System.Data;
using System.Data.SqlClient;
namespace LaunchJobAndWaitTillDone
{
class Program
{
const string connectionString = "Data Source=YOURSERVERNAMEHERE;Initial Catalog=msdb;Integrated Security=SSPI";
const string jobName = "YOURJOBNAMEHERE";
static readonly TimeSpan waitFor = TimeSpan.FromSeconds(1.0);
enum JobExecutionResult
{
Succeeded,
FailedToStart,
FailedAfterStart,
Unknown
}
static void Main(string[] args)
{
var instance = new Program();
JobExecutionResult jobResult = instance.RunJob(jobName);
switch (jobResult)
{
case JobExecutionResult.Succeeded:
Console.WriteLine($"SQL Server Agent job, '{jobName}', ran successfully to completion.");
break;
case JobExecutionResult.FailedToStart:
Console.WriteLine($"SQL Server Agent job, '{jobName}', failed to start.");
break;
case JobExecutionResult.FailedAfterStart:
Console.WriteLine($"SQL Server Agent job, '{jobName}', started successfully, but encountered an error.");
break;
default:
Console.WriteLine($"Unknown result from attempting to run SQL Server Agent job, '{jobName}'.");
break;
}
Console.ReadLine();
return;
}
JobExecutionResult RunJob(string jobName)
{
int jobResult;
using (var jobConnection = new SqlConnection(connectionString))
{
SqlCommand jobCommand;
SqlParameter jobReturnValue;
SqlParameter jobParameter;
jobCommand = new SqlCommand("sp_start_job", jobConnection);
jobCommand.CommandType = CommandType.StoredProcedure;
jobReturnValue = new SqlParameter("@RETURN_VALUE", SqlDbType.Int);
jobReturnValue.Direction = ParameterDirection.ReturnValue;
jobCommand.Parameters.Add(jobReturnValue);
jobParameter = new SqlParameter("@job_name", SqlDbType.VarChar);
jobParameter.Direction = ParameterDirection.Input;
jobCommand.Parameters.Add(jobParameter);
jobParameter.Value = jobName;
jobConnection.Open();
try
{
jobCommand.ExecuteNonQuery();
jobResult = (Int32)jobCommand.Parameters["@RETURN_VALUE"].Value;
}
catch (SqlException)
{
jobResult = -1;
}
}
switch (jobResult)
{
case 0:
break;
default:
return JobExecutionResult.FailedToStart;
}
while (true)
{
using (var jobConnection2 = new SqlConnection(connectionString))
{
SqlCommand jobCommand2 = new SqlCommand("sp_help_jobactivity", jobConnection2);
jobCommand2.CommandType = CommandType.StoredProcedure;
SqlParameter jobReturnValue2 = new SqlParameter("@RETURN_VALUE", SqlDbType.Int);
jobReturnValue2.Direction = ParameterDirection.ReturnValue;
jobCommand2.Parameters.Add(jobReturnValue2);
SqlParameter jobParameter2 = new SqlParameter("@job_name", SqlDbType.VarChar);
jobParameter2.Direction = ParameterDirection.Input;
jobCommand2.Parameters.Add(jobParameter2);
jobParameter2.Value = jobName;
jobConnection2.Open();
SqlDataReader rdr = jobCommand2.ExecuteReader();
while (rdr.Read())
{
object msg = rdr["message"];
object run_status = rdr["run_status"];
if (!DBNull.Value.Equals(msg))
{
var message = msg as string;
var runStatus = run_status as Int32?;
if (message != null && message.StartsWith("The job succeeded")
&& runStatus.HasValue && runStatus.Value == 1)
{
return JobExecutionResult.Succeeded;
}
else if (message != null && message.StartsWith("The job failed"))
{
return JobExecutionResult.FailedAfterStart;
}
else if (runStatus.HasValue && runStatus.Value == 1)
{
return JobExecutionResult.Unknown;
}
}
}
}
System.Threading.Thread.Sleep(waitFor);
}
}
}
}
请注意,您可能需要数据库/服务器所有者权限或类似的权限,此代码才能正常工作。