在您的服務器實例中,針對SQL Server 2005的提示里,在運行數據定義語言(Create,Alter,Drop)的命令中,你就可以看到如何跟蹤DDL的活動,但我們如何存儲這些事件,用來捕獲這些DDL觸發器并且存儲在表中為反饋的信息呢?
Solution解決方案
在SQL Server 2005中 ,您可以通過訪問eventdata ( )函數,用來觸發ddl事件而獲取數據。 這個函數返回的是服務器或數據庫事件的信息,并以XML數據類型的方式儲存在一個變量中使用。 我們需要做的是捕捉eventdata ( )函數返回的數據,并將它儲存在數據庫的表中為反饋的信息。在把數據存儲在表中的列之前,您可以把儲存的數據直接放在XML的一列或者過程中。
不過,由于返回的類型是XML ,我們需要運用的就是用XQuery所產生的數據的功能,以確定XML元素數據的返回,關于事件使用的索引或搜索相關的話題,請訪問SQL Server的聯機叢書。 由于這個特殊技巧,我們將使用表有關的事件。 該ddl_table_events類型說明什么數據可以捕獲一個CREATE,ALTER或者DROP表的事件。
讓我們來用Northwind數據庫來舉一個例子。 我們將創建一個表,將用來存儲eventdata ( )函數傳回來的數據。 我們從ALTER_TABLE事件引起的架構中只將選擇一些項目; 即在每個事件中包括TSQLCommand、PostTime、LoginName和EventType這樣的字段。
創建事件日志表
USE NorthwindUSE Northwind GO CREATE TABLE EvtLog ( PostTime DATETIME, LoginName NVARCHAR(100), EventType NVARCHAR(100), TSQLCommand NVARCHAR(2000) ) GO GO |
創建ddl觸發
CREATE TRIGGER trPreventTblChangeCREATE TRIGGER trPreventTblChange ON DATABASE FOR ALTER_TABLE AS DECLARE @Data XML SET @Data = EventData() INSERT EvtLog (PostTime, LoginName, EventType, TSQLCommand) VALUES (GETDATE(), CONVERT(NVARCHAR(100), CURRENT_USER), @Data.value('(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(100)'), @Data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(2000)') ) ; GO |
代碼walthrough
首先,我們聲明一個XML數據類型的變量,命名為@Data;
接下來,我們指派一個由EventData( )函數變量返回的值;
然后,在INSERT語句中,使用XQuery和value()方法,我們在@Data變量中檢索元素的值。我們使用@Data 的value()方法,作為兩個參量,當它是零索引的時候,代表的值是1,名字是其中一個SQL服務器固定的數據類型。 值返回的是作為那個類型的實例。 并且,value()方法讓您的XML數據的格式有更好的體現。
測試觸發
在Northwind數據庫中,讓我們在Reion的表中添加一個新的一列。
USE NorthwindUSE Northwind GO ALTER TABLE Region ADD newColumn SMALLDATETIME NULL |
請求的EvtLog表將給您EventData ()函數返回的數據,以表格的形式存放,而我們從觸發器的定義里邊已經獲取了在XML數據里面的元素的值。
下一步驟
您可以在對數據庫或服務器的層次上定義ddl觸發以及捕捉使用eventdata ( )函數活動的詳細信息。 這種做法只是為了當ddl事件發生時,把活動的詳情儲存在一個日志表中。為了確保你需要驗證的事件的執行,您也可以有一個中心數據庫,將所有在數據庫和服務器層次的事件存儲起來,在如此大數額的可驗證的日志操作中進行每一個事件的處理驗證,這就既不高效也不有效。