solving sql server problems for millions of dbas and developers since 2006



SQL Server DBA Tips SQL Server Developer Tips SQL Server Business Intelligence Tips SQL Server Career Tips SQL Server Tip Categories SQL Server Tutorials SQL Server Webcasts SQL Server Whitepapers SQL Server Tools SQL Server Questions and Answers MSSQLTips Authors About MSSQLTips SQL Server User Groups MSSLQTips Giveaways MSSQLTips Advertising Options

MSSQLTips Facebook Page MSSQLTips LinkedIn Page MSSQLTips RSS Feed MSSQLTips Twitter Page MSSQLTips Google+ Page

SQL Product Highlight

Idera - SQL diagnostic manager

SQL diagnostic manager is a powerful performance monitoring and diagnostics solution that proactively alerts administrators to health, performance or availability problems within their SQL Server environment via a central console or mobile device. SQL diagnostic manager minimizes costly server downtime by providing agent-less, real-time monitoring and customizable alerting for fast diagnosis and remediation of SQL Server performance and availability problems. SQL diagnostic manager also provides a 'community' environment where, using Idera's IntelliFeed(TM) technology DBAs form a community to collaborate to quickly resolve problems, perform maintenance and capture best practices.

Learn more!








Event Notifications in SQL Server for Tracking Changes

By: | Read Comments (6) | Print

Arshad is a SQL and BI Developer focusing on Data Warehousing projects for Microsoft.

Related Tips: More

Problem

As a DBA, we often need a way to track what events are occurring (changes that are being made) on SQL Server or at the database level. So what is a way to track these changes without much impact on SQL Server performance?

Solution

SQL Server 2005 and onwards provides event notifications mechanism for tracking all events or changes happening at the database or instance level. This can be done with DDL triggers or SQL traces, but event notifications have the advantage of being asynchronous in nature and running outside of the scope of the transaction and hence it can run inside (or be a part of) a database application to capture defined events without using the resources allocated to the transaction.

Event notification is a programmatic alternative to using DDL triggers or SQL traces and executes in the response to different DDL statements, SQL traces, Service Broker events (like QUEUE_ACTIVATION or BROKER_QUEUE_DISABLED) and then sends this information, in XML format, to the SQL Server Service Broker (SSB) service. In other words, when you create a notification, SQL Server tracks the defined events and the occurrence of that event is written to the SSB service and then you can retrieve this information asynchronously from the SSB queue when needed. Discussion of Service Broker is out of the scope of this tip, but you can learn more about SQL Server Service Broker here.

Let's get started...

In Script #1, I am first checking if Service Broker is enabled at the database level and if not then I am enabling it. Next I am creating a SSB queue and the SSB service will use this queue to store messages coming to this service. This service uses the built-in contract (a contract defines a type of message that can be sent to the SSB service), http://schemas.microsoft.com/SQL/Notifications/PostEventNotification, which is specifically for event notification. Note: you will need exclusive access to the database to run the alter database command.

Script #1 - Setting up environment for demonstration
--Check if the database is enabled for Service Broker
--If not then enable it
IF EXISTS (SELECT * FROM sys.databases WHERE name = 'AdventureWorks'
AND is_broker_enabled = 0)
ALTER DATABASE AdventureWorks SET ENABLE_BROKER;
GO
USE AdventureWorks
GO
--Create a queue which will hold the tracked information
CREATE QUEUE dbo.EventNotificationQueue
GO
--Check if the queue is created or not
SELECT * FROM sys.service_queues
WHERE name = 'EventNotificationQueue'
GO
--Create a service on which tracked information will be sent
CREATE SERVICE [//AdventureWorks/EventNotificationService]
ON QUEUE dbo.EventNotificationQueue
([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification])
GO
--Check if the service is created or not
SELECT * FROM sys.services
WHERE name = '//AdventureWorks/EventNotificationService'
GO

In Script #2, I am creating two database level notifications. The first will notify when there is a create table command execution and the second will notify when there is an alter table command execution. You can also create a notification event group; for example you can create a single notification with DDL_TABLE_EVENTS to track all events of a table like creation, alteration and drop.

Script #2 - Creating database level notification
--Create a notification to track create table command
CREATE EVENT NOTIFICATION NotifyCREATETABLEEvents
ON DATABASE
FOR CREATE_TABLE
TO SERVICE '//AdventureWorks/EventNotificationService' , 'current database'
GO
--Create a notification to track alter table command
CREATE EVENT NOTIFICATION NotifyALTERTABLEEvents
ON DATABASE
FOR ALTER_TABLE
TO SERVICE '//AdventureWorks/EventNotificationService' , 'current database'
GO
--Check if both the above notifications created or not
SELECT * FROM sys.event_notifications
WHERE name IN ('NotifyCREATETABLEEvents','NotifyALTERTABLEEvents')
GO

In Script #3, I am creating a server level notification that will be raised whenever an error is raised at the SQL Server instance level. You can query the sys.server_event_notifications catalog view to check if a notification exists on the server or not.

Script #3 - Creating server level notification
--Create a notification to error occuring at server level
CREATE EVENT NOTIFICATION NotifyERROREvents
ON SERVER WITH FAN_IN
FOR ERRORLOG
TO SERVICE '//AdventureWorks/EventNotificationService', 'current database'
GO
--Check if the above notification was created or not
SELECT * FROM sys.server_event_notifications
WHERE name IN ('NotifyERROREvents')
GO

In Script #4, let's verify if these event notifications are actually working. In this script, I am creating a table, then altering it, which will be tracked by both the database level event notifications we created above and then I am using RAISERROR (WITH LOG clause is required to be tracked by server level event notification) to generate an error in SQL Server which will be tracked by our last server level event notification.

Script #4 - Generating database and server level events
--Generate a create table event
CREATE TABLE ABC
(
COL1 INT,
COL2 INT
)
GO
--Generate an alter table event
ALTER TABLE ABC
ADD COL3 INT
GO
--Generate a server level event
RAISERROR (N'Generating error for Event Notification testing...', 16, 1)
WITH LOG
GO
--Review if the events were tracked in queue
SELECT CAST(message_body AS XML) AS message_in_xml
FROM dbo.EventNotificationQueue
GO

In Script #5, event notifications send tracked information to the SSB service in XML format; you can query the queue to see the tracked information, but you need to use the RECEIVE command to retrieve messages from the queue, process them and remove them from the queue as shown below. With the RECEIVE command you can specify the number of records you want to retrieve at one time. In this script, I am using a TOP(1) command to retrieve the top 1 record form the queue and displaying the information that it contains. Event notification sends information in XML format (remember we used the built-in contract with the service we created that defines that only XML data can be written to the service) and that's the reason I am casting the message body to an XML data type. Since I am using a TOP(1) clause with the RECEIVE command, I ran the below command 3 times, since there were 3 records in the queue. You can see the result in the image below the query. You can also use a looping construct to read all the records from the queue instead of running the same script multiple times.

Script #5 - Retrieving records from the queue
DECLARE @TargetDialogHandle UNIQUEIDENTIFIER;
DECLARE @EventMessage XML;
DECLARE @EventMessageTypeName sysname;
WAITFOR
( RECEIVE TOP(1)
@TargetDialogHandle = conversation_handle,
@EventMessage = CONVERT(XML, message_body),
@EventMessageTypeName = message_type_name
FROM dbo.EventNotificationQueue
), TIMEOUT 1000;
SELECT @TargetDialogHandle AS DialogHandle, @EventMessageTypeName AS MessageTypeName,
@EventMessage.value('(/EVENT_INSTANCE/EventType)[1]', 'varchar(128)' ) as EventType,
@EventMessage.value('(/EVENT_INSTANCE/ServerName)[1]', 'varchar(128)' ) as ServerName,
@EventMessage.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'varchar(128)' ) as DatabaseName,
@EventMessage.value('(/EVENT_INSTANCE/LoginName)[1]', 'varchar(128)' ) as LoginName,
@EventMessage.value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)') AS TSQLCommand,
@EventMessage.value('(/EVENT_INSTANCE/TextData)[1]', 'varchar(128)' ) AS TextData,
@EventMessage.value('(/EVENT_INSTANCE/Severity)[1]', 'varchar(128)' ) AS Severity,
@EventMessage.value('(/EVENT_INSTANCE/Error)[1]', 'varchar(128)' ) AS ErrorNumber

SQL Server 2005 and onwards provides event notifications mechanism for tracking all events or changes happening at the database or instance level

In Script #6, you can use this code to cleanup and drop all the objects, in the reverse order of their creation, which we created for this demonstration.

Script #6 - Cleaning up the objects created
DROP EVENT NOTIFICATION NotifyCREATETABLEEvents ON DATABASE
GO
DROP EVENT NOTIFICATION NotifyALTERTABLEEvents ON DATABASE
GO
DROP EVENT NOTIFICATION NotifyERROREvents ON SERVER
GO
DROP TABLE ABC
GO
DROP SERVICE [//AdventureWorks/EventNotificationService]
GO
DROP QUEUE dbo.EventNotificationQueue
GO

Permission Requirements

  • In order to create a database level event notification, you need to have CREATE DATABASE DDL EVENT NOTIFICATION permissions in that database. To drop it, you must be the owner of the event notification or have ALTER ANY DATABASE EVENT NOTIFICATION permission in that database.
  • In order to create a server level notification, you need to have CREATE DDL EVENT NOTIFICATION permissions on the server. To drop it, you must be the owner of the event notification or have ALTER ANY EVENT NOTIFICATION permission on the server.
  • In order to create an event notification to track SQL traces, you need to have CREATE TRACE EVENT NOTIFICATION permission on the server. To drop it, you must be the owner of the event notification or have ALTER ANY EVENT NOTIFICATION permission on the server.
  • In order to create a queue scoped event notification you need ALTER permission on the queue. To drop it, you must be the owner of the event notification or have ALTER permission on the queue.

Notes

  • You can query sys.event_notification_event_types to get the list of all the events on which you can create event notifications or you can view DDL events, DDL event groups, SQL trace events, SQL trace event groups.
  • To see the differences between event notifications and triggers click here and differences between event notifications and SQL traces click here.
  • You cannot directly alter a notification, you need to drop and re-create it.

Next Steps



Related Tips: More | Become a paid author


Last Update: 9/27/2010

Share: Share 






Comments and Feedback:

Monday, September 27, 2010 - 9:35:59 AM - Ranga Read The Tip
Good article, very simple and precise.


Friday, October 08, 2010 - 6:12:44 PM - Amin Mesbahi Read The Tip
Thanks for your article but SSNS (SQL Server Notification Services) is a discontinued feature since SQL Server 2008...

This feature is useful only in SQL Server 2005 not lower versions not highr versions!


Saturday, October 09, 2010 - 2:42:06 AM - Arshad Read The Tip
Hi Amin,

Event notification is a feature based on SQL Server Service Broker and available even in SQL Server 2008 and SQL Server 2008 R2 as well. Hope it helps. Please let me know if you have any doubts.


Wednesday, October 20, 2010 - 1:40:24 PM - Manoj Read The Tip
I am trying to implement a feature in SQL Server so that when a new login is created in SQL Server 2005, it should raise an event so that the client application can add the newly created login info to another custom table.

I recently read about deprecation of SQL Server Notification Services in SQL Server 2008. Although I am not very sure that if that was the right solution for this problem.

Does anyone know what would be a correct solution for such a problem? Which feature to use to send a notification to another program that a new login has been created in SQL Server 2005.


Monday, January 09, 2012 - 10:47:27 PM - Aaron Bertrand Read The Tip

I know it's been 13 months but I just wanted to mention that event notifications and notification services are two very different concepts. While the latter is deprecated the former is certainly not.


Tuesday, January 10, 2012 - 5:28:18 AM - Arshad Read The Tip

Yes you are absolutely right Aaron,

You might also like to have look on extended events features of SQL Server 2008 and later versions which provide more granular level control on tracing :

http://www.mssqltips.com/sqlservertip/2144/an-overview-of-extended-events-in-sql-server-2008/



Post a Comment or Question

Keep it clean and stay on the subject or we may delete your comment.
Your email address is not published. Required fields are marked with an asterisk (*)

*Name   *Email   Notify for updates
Comments
*Enter Code refresh code


 
Sponsor Information
"SQL diagnostic manager delivers response in minutes, not hours!"

Time-strapped database professionals use SQL Monitor to look after their servers. Try it online.

What grade do you think your SQL Servers get? Find out with Edgewood's SQL Server Health Check consulting services.

Free Trial: Get Proactive Insight with SpotlightŪ for SQL Server Enterprise.

Solving SQL Server problems for millions of DBAs and Devs since 2006. Join now.

Demystify TempDB Performance and Manageability


Copyright (c) 2006-2012 Edgewood Solutions, LLC All rights reserved
privacy | disclaimer | copyright | advertise | about
authors | contribute | feedback | giveaways | user groups
Some names and products listed are the registered trademarks of their respective owners.


Edgewood Solutions LLC | MSSharePointTips.com | MSSQLTips.com