SQL Server事件通知有什麼用呢?若是你想監控SQL Server的DDL操做,你能夠經過DDL觸發器(參考:SQL Server DDL觸發器運用),也能夠經過SQL Server 事件通知把這個事件相關的信息發送到 Service Broker 服務;他們最大的區別就是DDL觸發器能夠進行ROLLBACK,而事件通知不行;還有,事件通知是異步發送消息的;html
SQL Server 事件通知還能夠響應部分SQL跟蹤事件,即SQL Trace (參考:SQL Server 默認跟蹤(Default Trace)、SQL Server 建立跟蹤);他們最大的區別就是跟蹤事件能夠自定義生成哪些數據列,而事件通知是生成固定的XML;還有,每次從新啓動服務器時,都必須從新啓動跟蹤。sql
事件通知將有關事件的信息發送給 Service Broker 服務。執行事件通知可對各類 Transact-SQL 數據定義語言 (DDL) 語句和 SQL跟蹤事件作出響應,並將這些事件的相關信息發送到 Service Broker 服務。數據庫
事件通知能夠用來執行如下操做:編程
能夠將事件通知用做替代 DDL 觸發器和 SQL 跟蹤的編程方法,由於你能夠經過讀取Service Broker 服務中的隊列,在程序中對信息進行處理。安全
事件信息做爲 xml 類型的變量傳遞給 Service Broker 服務,它提供了有關事件的發生時間、受影響的數據庫對象、涉及的 Transact-SQL 批處理語句的信息以及其餘信息。服務器
下圖是我對事件通知邏輯關係的理解,當數據庫A或者實例B產生DDL就會激發事件通知,這個通知把相應的DDL的XML信息發送給隊列,你能夠經過SQL獲取到隊列中的XML;異步
(Figure1:事件通知邏輯關係圖)async
建立事件通知的event_type參數 能夠爲 Transact-SQL DDL 事件類型、SQL 跟蹤事件類型或 Service Broker 事件類型有關限定 Transact-SQL DDL 事件類型的列表,請參閱 DDL事件。 Service Broker 事件類型爲 QUEUE_ACTIVATION 和 BROKER_QUEUE_DISABLED。 有關詳細信息,請參閱事件通知。性能
數據庫的DDL操做默認會被記錄到Default Trace默認跟蹤中(參考:SQL Server 默認跟蹤(Default Trace)),這是一個被動式的監控;而主動式的監控就可使用DDL觸發器(參考:SQL Server DDL觸發器運用);咱們還可使用事件通知的形式監控DDL,下面就着重講講實現過程。測試
下面建立一個SSB_DB數據庫,捕獲數據庫實例的DDL語句;
--Step1:建立示例數據庫 USE master GO IF EXISTS(SELECT name FROM sys.databases WHERE name = 'SSB_DB') DROP DATABASE SSB_DB GO CREATE DATABASE SSB_DB GO USE SSB_DB GO --Step2:建立隊列,默認爲開啓 CREATE QUEUE NotifyQueue_DDL --WITH STATUS=ON GO --Step3:建立服務 CREATE SERVICE NotifyService_DDL ON QUEUE NotifyQueue_DDL ([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification]); GO --Step4:對系統目錄視圖sys.databases進行查詢 SELECT service_broker_guid FROM sys.databases WHERE name = 'SSB_DB' /* DB19CBE8-0581-4604-B44A-812C29A565BB */ --Step5:建立事件通知,使用上面返回的GUID值 CREATE EVENT NOTIFICATION NotifyEvent_DDL ON DATABASE FOR DDL_DATABASE_LEVEL_EVENTS TO SERVICE 'NotifyService_DDL', 'DB19CBE8-0581-4604-B44A-812C29A565BB'; --Step6:測試 CREATE TABLE TestTable (a int) GO DROP TABLE TestTable; GO --Step7:使用Select或Recieve(其中Recieve會刪除隊列中的事件消息)查詢隊列 SELECT CAST(message_body as xml) EventInfo FROM dbo.NotifyQueue_DDL
上面的SQL腳本,你須要注意如下幾點:
1. 建立的EVENT NOTIFICATION是針對當前數據庫的(ON DATABASE),只有在當前數據庫發生的DDL纔會被捕獲;
2. 使用DDL_DATABASE_LEVEL_EVENTS將會監控當前數據庫全部DDL事件,你可使用DDL_SERVER_LEVEL_EVENTS監控數據庫實例的DDL操做,更多的DDL事件能夠參考:DDL 事件組;
3. 關於service_broker_guid,你應該經過查詢確認這個值,它的做用是指定解析 broker_service 所依據的 Service Broker 實例。
執行Step7返回下圖的結果,這是執行Step6腳本產生的兩條DDL消息:
(Figure3:DDL事件在隊列中的XML信息)
經過下面的SQL腳本能夠對Figure4所示的XML進行解釋,保存到表中:
執行Step10將返回Figu
--Step8:建立表 CREATE TABLE [dbo].[EventInfo]( [EventInfoID] [int] IDENTITY(1,1) NOT NULL, [PostTime] [datetime] NOT NULL, [ServerName] [sysname] NOT NULL, [LoginName] [sysname] NOT NULL, [DatabaseUser] [sysname] NOT NULL, [DatabaseName] [sysname] NOT NULL, [Schema] [sysname] NULL, [Object] [sysname] NULL, [TSQL] [nvarchar](max) NOT NULL, [Event] [sysname] NOT NULL, [XmlEvent] [xml] NOT NULL, CONSTRAINT [PK_EventInfo_EventInfoID] PRIMARY KEY NONCLUSTERED ( [EventInfoID] ASC ) ON [PRIMARY] ) ON [PRIMARY] --Step9:建立分離XML的存儲過程 -- ============================================= -- Author: <聽風吹雨> -- Create date: <2013.06.19> -- Description: <分離XML> -- Blog: <http://www.cnblogs.com/gaizai/> -- ============================================= CREATE PROCEDURE sp_SeparateXML AS BEGIN SET NOCOUNT ON; DECLARE @data XML DECLARE @itemCur CURSOR SET @itemCur = CURSOR FOR SELECT CAST(message_body as xml) EventInfo FROM [SSB_DB].[dbo].NotifyQueue_DDL OPEN @itemCur FETCH NEXT FROM @itemCur INTO @data WHILE @@FETCH_STATUS=0 BEGIN --邏輯處理 INSERT [SSB_DB].[dbo].[EventInfo]( [PostTime], [ServerName], [LoginName], [DatabaseUser], [DatabaseName], [Schema], [Object], [TSQL], [Event], [XmlEvent]) VALUES( @data.value(