DML 觸發器、DDL 觸發器和登錄觸發器

MicrosoftSQL Server 提供兩種主要機制來強制使用業務規則和數據完整性:約束和觸發器。觸發器爲特殊類型的存儲過程,可在執行語言事件時自動生效。SQL Server 包括三種常規類型的觸發器:DML 觸發器DDL 觸發器登錄觸發器

1、當數據庫中發生數據操作語言 (DML) 事件時將調用 DML 觸發器。DML 事件包括在指定表或視圖中修改數據的 INSERT 語句、UPDATE 語句或 DELETE 語句。DML 觸發器可以查詢其他表,還可以包含複雜的 Transact-SQL 語句。將觸發器和觸發它的語句作爲可在觸發器內回滾的單個事務對待。如果檢測到錯誤(例如,磁盤空間不足),則整個事務即自動回滾。

關於DML觸發器應用最爲廣泛。這裏不再贅述。MSDN官方說明:http://msdn.microsoft.com/zh-cn/library/ms189799.aspx

2、當服務器或數據庫中發生數據定義語言 (DDL) 事件時將調用 DDL 觸發器。DDL 觸發器是一種特殊的觸發器,它在響應數據定義語言 (DDL) 語句時觸發。它們可以用於在數據庫中執行管理任務,例如,審覈以及規範數據庫操作。

下面我們用舉例說明DDL觸發器(http://technet.microsoft.com/zh-cn/library/ms189799%28SQL.90%29.aspx)的應用:

     示例一:創建一個DDL觸發器審覈數據庫級事件

複製代碼
/***************
創建一個審覈表,其中EventData是一個XML數據列
[email protected]
******************
*/

USE master
GO
CREATETABLE dbo.ChangeAttempt
(EventData xml 
NOTNULL,
AttemptDate 
datetimeNOTNULLDEFAULTGETDATE(),
DBUser 
char(50NOTNULL)
GO

/***************
在目標數據庫上創建一個觸發器,以記錄該數據庫的索引變化動作,
包括Create|alter|Drop
[email protected]
******************
*/

CREATETRIGGER db_trg_RestrictINDEXChanges
ONDATABASE
FOR CREATE_INDEX, ALTER_INDEX, DROP_INDEX
AS
SET NOCOUNT ON
INSERT dbo.ChangeAttempt
(EventData, DBUser)
VALUES (EVENTDATA(), USER)
GO

/***************
創建一個索引,以測試觸發器
[email protected]
******************
*/

CREATENONCLUSTEREDINDEX ni_ChangeAttempt_DBUser ON
dbo.ChangeAttempt(DBUser)
GO

/***************
查看審覈記錄
[email protected]
******************
*/

SELECT EventData
FROM dbo.ChangeAttempt



--------/***************
--
------刪除測試觸發器和記錄表
--
[email protected]
--
------*******************/

----drop TRIGGER [db_trg_RestrictINDEXChanges]
--
--ON DATABASE
--
--go
--
--drop table dbo.ChangeAttempt
--
--go
複製代碼

 

執行結果:

邀月工作室

    示例二:創建一個DDL觸發器審覈服務器級事件 

複製代碼
--------/***************
--
------在目標數據庫服務器上創建一個觸發器,以防止添加登錄賬號,
--
[email protected]
--
------*******************/
USE master
GO
-- Disallow new Logins on the SQL instance
CREATETRIGGER srv_trg_RestrictNewLogins
ONALL SERVER
FOR CREATE_LOGIN
AS
PRINT'No login creations without DBA involvement.'
ROLLBACK
GO

--------/***************
--
------試圖創建一個登錄賬號
--
[email protected]
--
------*******************/
CREATE LOGIN johny WITH PASSWORD ='123456'
GO

--------/***************
--
------刪除演示觸發器
--
[email protected]
--
------*******************/

dropTRIGGER srv_trg_RestrictNewLogins
ONALL SERVER
go
複製代碼

 

效果:

邀月工作室

注意:要特別謹慎使用DDL觸發器。如果設置不當,將會在數據庫級甚至服務器級引發不可預知的後果。

 

3、登錄觸發器(http://msdn.microsoft.com/zh-cn/library/bb326598.aspx)將爲響應 LOGON 事件而激發存儲過程。與 SQL Server 實例建立用戶會話時將引發此事件。

如果你有這樣的需求:在某個特定的時間只允許某個賬號登錄服務器(如單位和家裏使用不同的賬號遠程登錄服務器),那麼登錄觸發器是一個不錯的選擇。

    示例三:創建一個登錄觸發器審覈登錄事件

複製代碼
--------/***************
--
------創建登錄賬號
--
[email protected]
--
------*******************/

CREATE LOGIN nightworker WITH PASSWORD ='123b3b4'
GO

--------/***************
--
------演示數據庫和審覈表
--
[email protected]
--
------*******************/

CREATEDATABASE ExampleAuditDB
GO
USE ExampleAuditDB
GO

CREATETABLE dbo.RestrictedLogonAttempt
(LoginNM sysname 
NOTNULL,
AttemptDT 
datetimeNOTNULL)
GO

--------/***************
--
------創建登錄觸發器,如果不是在7:00-17:00登錄,則記錄審覈日誌,並提示失敗
--
[email protected]
--
------*******************/

USE master
GO
CreateTRIGGER trg_logon_attempt
ONALL SERVER
WITHEXECUTEAS'sa'
FOR LOGON
AS
BEGIN
IF ORIGINAL_LOGIN()='nightworker'AND
DATEPART(hh,GETDATE()) BETWEEN7AND17
BEGIN
ROLLBACK
INSERT ExampleAuditDB.dbo.RestrictedLogonAttempt
(LoginNM, AttemptDT)
VALUES (ORIGINAL_LOGIN(), GETDATE())
END
END
GO

--------/***************
--
------查看審覈記錄
--
[email protected]
--
------*******************/
USE ExampleAuditDB
GO
select*from dbo.RestrictedLogonAttempt
go

--------/***************
--
------刪除演示數據庫及演示觸發器
--
[email protected]
--
------*******************/
use master
go

dropTRIGGER trg_logon_attempt
ONALL SERVER
go

dropdatabase ExampleAuditDB
go
複製代碼

 

結果:

邀月工作室

邀月工作室

當然,你也可以使用應用程序或類似於log4net的日誌機制記錄類似的登錄事件,但SQL server 2008已經爲我們做到了,你所做的僅僅是有勇氣來試一試。

小結:作爲對數據DDL操作和登錄事件的審覈和監控,SQL Server提供了比較完善的事件處理機制。這也是SQL server安全機制的一部分。下文將涉及SQL server數據庫級的透明加密,敬請關注。

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