Как отслеживать информацию о работе агента SQL Server в C #

Мне нужно создать приложение для мониторинга состояния и информации о статусе агента SQL Server 2000, когда Job будет таким же, как и в журнале событий приложений Windows. Теперь я подключаюсь к базе данных уже через строку подключения, но я не знаю, как получить статус и информацию из Job.

Мне нужно показать статус и информацию в текстовом поле.

Что вы предлагаете, как это сделать.

Инструменты разработчика :

  1. MS SQL Sever 2000 SP4
  2. MS Visual Studio 2008 (C #)

Я новичок-программист.

я могу сделать это уже …

Я выбираю таблицу форм «Sysjobserver» в базе данных «msdb» для статуса чтения, даты, времени работы, которое я хочу.

используйте этот код

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(); } } 

Большое спасибо за помощь. 😀

SQL хранимые процедуры запросов не дают вам каких-либо системных данных, если у вас нет прав db_owner в системной базе данных msdb при сдаче в аренду в SQL Server 2008. Поэтому упомянутые методы обычно не работают для приложений, где вы хотите показывать или управлять заданиями. Однако пространство имен SMO предоставляет вам решение с управляемым кодом для многих функций управления SQL Server, включая функции агента SQL Server, которые требуют только разрешения SQLServerAgent *, которые вы обычно можете отсортировать для пользователя вашего приложения. Здесь вы найдете хорошее руководство по использованию classов 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); } } } } 

Это должно быть хорошей отправной точкой, чтобы узнать, как найти задания SQL Agent с помощью T-SQL:

Просмотр (и отключить) SQL Agent Jobs с TSQL

В сценарии будут перечислены все ваши задания в вашей базе данных, и когда они будут запущены дальше и так далее.

Используя имя job_name, вы также сможете узнать подробности о своих заданиях с помощью хранимых процедур агента SQL Server в msdb данных msdb на вашем сервере.

В SQL Server 2005 и выше вы можете использовать системную хранимую процедуру msdb.dbo.sp_help_job для получения информации, в том числе о статусе, о работе агента SQL Server. Вы можете узнать больше о sp_help_job по адресу http://msdn.microsoft.com/en-us/library/ms186722(v=SQL.90).aspx .

Вот пример кода для этого с C #.

 private Dictionary ExecutionStatusDictionary = new Dictionary() { {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=GACDTL01CR585M;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(); } 

Вы можете получить список всех заданий сервера, используя этот SELECT:

 SELECT [name] FROM msdb.dbo.sysjobs 

Если вы хотите получить список текущих рабочих заданий и их информацию, я бы рекомендовал написать хранимую процедуру в SQL, которую вызывает ваше приложение. Здесь есть хорошая демонстрация, которую вы могли бы использовать …

http://feodorgeorgiev.com/blog/2010/03/how-to-query-currently-running-sql-server-agent-jobs/

Удачи!

Для моего случая использования я определенно должен был знать, когда работа была закончена, и было ли это выполнено. Вот мой код:

 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); } } } } 

Обратите внимание, что вам могут потребоваться разрешения владельца базы данных / сервера или что-то в этом роде для работы этого кода.

Давайте будем гением компьютера.