SQL Server DDL 觸發器(Trigger)-- 創建服務器級別的DDL觸發器

SQL Server DDL 觸發器(Trigger)-- 創建服務器級別的DDL觸發器

 

若是創建服務器級別的DDL觸發器,只要把先前的ON DATABASE改爲ON ALL SERVER,即可跟蹤服務器級別的事件,使用的原理與數據庫級別的DDL觸發器相似,區別只在跟蹤的事件不同。

 

CREATE TRIGGER ddl_trig_login
ON ALL SERVER
FOR DDL_LOGIN_EVENTS
AS
PRINT n’ALTER LOGIN EVENT’
SELECT EVENTDATA().value(‘(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]’,’nvarchar(max)’)

 

跟蹤DDL_LOGIN_EVENTS類型事件,只要有新建、修改、刪除登錄帳號的事件發生,觸發器就會執行程序,同樣也可以利用EVENTDATA()函數取得觸發器執行時相關的系統信息。可以通過如下語句來測試:

 

CREATE LOGIN test WITH PASSWORD=’Mpdfzh7’

 

同樣地,如果要刪除服務器級別的DDL觸發器,和數據庫級別的DDL觸發器差不多,只是改成ON ALL SERVER即可,請參考如下語句:

 

DROP TRIGGER ddl_trig_login
ON ALL SERVER

 

當要禁止某個人或某個應用程序登錄SQL Server時,也可以通過LOGON事件所引發的觸發器。例如,SQL Server 2008後,Management Studio所提供的T-SQL IntelliSense功能會佔據少許服務器的CPU和內存資源。若服務器端的數據對象不多,影響較小;但若對象很多,同時聯機編輯的用戶也很多,則會耗掉較大的資源。你可以通過LOGON事件所引發的觸發器。不準SQL Server Management Studio工具程序用來查詢T-SQL IntelliSense所需數據的連接登錄。

 

首先,通過SQL Server Profiler工具程序觀察,當Management Studio的T-SQL編輯器要取得服務器端數據對象,以提供開發程序T-SQL IntelliSense時,會用什麼樣的應用程序名稱登錄SQL Server,錄製結果如下。(備註:作者使用SQL Server 2012錄製,沒有捕獲到該應用的相關事件,下面測試在SQL Server 2008 R2下完成,SQL Server 2008 R2 Management Studio的T-SQL編輯環境會先查詢服務器端的對象後,再提供T-SQL編寫時的IntelliSense功能)

 

clip_image001

 

針對LOGON事件,創建簡單服務器級別的DDL觸發器後,通過APP_NAME系統函數判斷登錄的應用程序名稱,若類似“Microsoft SQL Server Management Studio - Transact-SQL IntelliSense”,便通過ROLLBACK命令使其無法連接,代碼如下。

 

CREATE TRIGGER IntelliSense_Connection_Limit_Trigger
ON ALL SERVER FOR LOGON
AS
BEGIN
IF APP_NAME() LIKE ‘% Microsoft SQL Server Management Studio - Transact-SQL IntelliSense %’
ROLLBACK;
END;

 

執行之後,SQL Server 2008 R2 Management Studio的T-SQL編輯器所提供的IntelliSense功能就失效了。

 

利用相同的技巧,也可以寫一個DDL觸發器,當服務器連接過多時,就不準再創建新的、不重要的連接,以維持數據庫的穩定和效率,並讓既有的連接得以完成工作。免得系統在極爲忙碌時,再加一條連接,有如最後一根稻草,壓垮已經運行一陣的其他業務。不過,若真這麼做,你可能要爲了服務器的管理而跟開發人員吵架了。

 

另外,當設置SQL Server 2008 R2所提供的“Policies”機制,其“Evaluation Mode”爲“on change -- prevent”時,SQL Server也是利用服務器幾倍的DDL觸發器,在事件發生後,立即評估其操作內容是否符合先前指定的策略,若違反策略,便ROLLBACK回滾原始狀況。

 

clip_image002

 

clip_image003

 

在設置“Policies”時,需要“Evaluation Mode”爲“on change -- prevent”,且“Enabled”,纔會自動創建服務器級別的DDL觸發器。若實際觀察該觸發器,可以看到如下內容。

 

CREATE TRIGGER [syspolicy_server_trigger] ON ALL SERVER
WITH EXECUTE AS '##MS_PolicyEventProcessingLogin##'
FOR ALTER_AUTHORIZATION_DATABASE,ALTER_PROCEDURE,ALTER_SCHEMA,CREATE_PROCEDURE,RENAME
AS
BEGIN
DECLARE @event_data xml
SELECT @event_data = EVENTDATA()
EXEC [msdb].[dbo].[sp_syspolicy_dispatch_event] @event_data = @event_data, @synchronous = 1
END


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章