Neste artigo de número 300, vermos uma funcionalidade bem interessante do SMO, que permite capturar eventos do SQL Server, seja em nível de instância, de banco de dados ou até no nível de tabela, permitindo monitorar criação e alterações de estruturas e configurações do SQL Server sem a necessidade de usar triggers ou trace, tudo por meio do serviço de notificações de eventos do Service Broker. Mas se você não “manja” de Service Broker, fique tranquilo, o SMO permite a utilização desta funcionalidade de forma bem transparente.
Neste exemplo, veremos como capturar/monitorar eventos de criação de banco de dados e de tabelas com o SMO:
using System;
using System.Linq;
using System.Xml.Linq;
using Microsoft.SqlServer.Management.Smo;
namespace DemoSmo
{
static class DemoEvent1
{
public static void Run()
{
// Definindo um grupo de eventos a serem monitorados
var eventSet = new ServerEventSet(ServerEvent.CreateDatabase, ServerEvent.CreateTable);
// Relacionando os eventos a uma instância do SQL Server
// e definindo o método OnCreate para o tratamento destes eventos
const string serverName = @".\SQLEXPRESS";
var server = new Server(serverName);
server.Events.SubscribeToEvents(eventSet, OnCreate);
// Iniciando a captura dos eventos
server.Events.StartEvents();
Console.ReadKey();
// Executando alguns comandos para testar se os eventos estão sendo monitorados
const string query = @"
USE [master]
GO
CREATE DATABASE [NovoBanco]
GO
USE [NovoBanco]
CREATE TABLE [NovaTabela] (CODIGO INT)
GO
USE [master]
GO
DROP DATABASE [NovoBanco]
GO";
server.ConnectionContext.ExecuteNonQuery(query);
// Terminando a captura dos eventos
Console.ReadKey();
server.Events.StopEvents();
server.Events.UnsubscribeFromEvents(eventSet);
}
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
switch (e.EventType)
{
case EventType.CreateDatabase:
Console.WriteLine("Foi criado um banco de dados!");
break;
case EventType.CreateTable:
Console.WriteLine("Foi criada uma tabela!");
break;
}
// Relacionando outras propriedades que serão exibidas
var showProperties = new[] { "DatabaseName", "TableName", "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 os eventos serão exibidos neste exemplo:

Próxima semana, eu pretendo demonstrar como capturar/monitorar eventos em um nível mais específico, e na última semana deste mês, veremos como monitorar alguns eventos que vão além de alterações estruturais do banco de dados.
Muito bom Paulo,
Eu imagino que esse seja um “Event Notification” na versão SMO.
[ ]s,
Gustavo
Sim, isso mesmo, só não coloquei com este nome pois “Event Notification com SMO” diria muito para quem já conhece esta feature, mas seria muito pouco intuitivo para quem só quer conhecer um pouco do “How to”.
Obrigado pelo comentário!!