Assim como explicado no artigo da semana passada, o monitoramento de eventos do SMO pode capturar eventos tanto no nível mais macro do SQL Server, quanto nos níveis mais específicos, como eventos relativos a tabelas ou outras estruturas do banco de dados.
Quem viu o artigo da semana passada irá perceber que não há muita diferença para capturar eventos de objetos específicos do SQL Server, pois as diferenças básicas são os objetos aos quais se associam os eventos (eventos de banco de dados, se associa a um objeto Database, eventos de instancia, a um objeto Server) e o grupo de eventos (EventSet) a ser utilizado para identificar quais os eventos que serão monitorados.
No exemplo a seguir veremos como implementar a captura de eventos de um determinado banco de dados:
using System;
using System.Linq;
using System.Xml.Linq;
using Microsoft.SqlServer.Management.Smo;
namespace DemoSmo
{
static class DemoEvent2
{
public static void Run()
{
// Definindo um grupo de eventos a serem monitorados
var dbEventSet = new DatabaseEventSet(DatabaseEvent.CreateTable);
// Relacionando os eventos de um determinado banco de dados
// e definindo o método OnCreate para o tratamento destes eventos
const string serverName = @".\SQLEXPRESS";
var server = new Server(serverName);
#region Criando um banco de dados
var db1 = new Database(server, "NovoBanco");
db1.Create();
#endregion
var database = server.Databases["NovoBanco"];
database.Events.SubscribeToEvents(dbEventSet, OnCreate);
// Iniciando a captura dos eventos
database.Events.StartEvents();
#region Criando uma tabela no banco de dados criado
Console.ReadKey();
var table1 = new Table(db1, "NovaTabela", "dbo");
table1.Columns.Add(new Column(table1, "Codigo", DataType.Int) { Nullable = false });
table1.Create();
#endregion
// Terminando a captura dos eventos
Console.ReadKey();
database.Events.StopEvents();
database.Events.UnsubscribeFromEvents(dbEventSet);
#region Excluindo o banco de dados criado
db1.Drop();
#endregion
}
private static void OnCreate(object sender, ServerEventArgs e)
{
// Exibindo o SPID e a data do evento
Console.WriteLine("SPID: {0}", e.Spid);
Console.WriteLine("Data: {0:dd/MM/yyyy HH:mm}", e.PostTime);
// Exibindo informações sobre o que foi executado
Console.WriteLine("Foi criada uma tabela!");
// Relacionando outras propriedades que serão exibidas
var showProperties = new[] { "DatabaseName", "LoginName" };
var properties = e.Properties.Where(prop => showProperties.Contains(prop.Name));
foreach (var prop in properties)
{
Console.WriteLine("{0}: {1}", prop.Name, prop.Value);
}
// Exibindo o comando que acionou o evento
var command = e.Properties.FirstOrDefault(prop => prop.Name == "TSQLCommand");
if (command != null)
{
var xml = XDocument.Parse((string)command.Value)
.Elements("TSQLCommand")
.Elements("CommandText")
.FirstOrDefault();
if (xml != null)
{
Console.WriteLine("CommandText: {0}", xml.Value);
}
}
Console.WriteLine();
}
}
}
E como resultado deste exemplo:

Aqueles que gostariam de saber como funciona a implementação de eventos de notificação, podem encontrar no link abaixo referências de como implementá-los com T-SQL, no qual conhecimento de Service Broker será indispensável:
http://msdn.microsoft.com/en-us/library/ms178080.aspx
1 Resposta para “Capturando eventos de um determinado bancos de dados com .NET via SMO sem Triggers ou Trace”