在本教程中,将学习如何使用SQL Server数据定义语言(DDL)触发器来监视对数据库对象所做的更改。
SQL Server DDL触发器简介
SQL Server DDL触发器响应服务器或数据库事件而不是表数据修改。 这些事件由Transact-SQL语句创建,通常以以下关键字之一:CREATE
,ALTER
,DROP
,GRANT
,DENY
,REVOKE
或UPDATE STATISTICS
开头。
例如,只要用户发出CREATE TABLE
或ALTER TABLE
语句,就可以编写DDL触发器来记录。
DDL触发器在以下情况下很有用:
- 记录数据库模式中的更改。
- 防止对数据库模式进行某些特定更改。
- 响应数据库模式的更改。
以下显示了创建DDL触发器的语法:
CREATE TRIGGER trigger_name
ON { DATABASE | ALL SERVER}
[WITH ddl_trigger_option]
FOR {event_type | event_group }
AS {sql_statement}
在上面语法中,
trigger_name
- 在CREATE TRIGGER
关键字后指定用户定义的触发器名称。 请注意,不必为DDL触发器指定模式,因为它与实际的数据库表或视图无关。DATABASE | ALL SERVER
- 如果触发器响应数据库范围的事件,则使用DATABASE
;如果触发器响应服务器范围的事件,则使用ALL SERVER
。ddl_trigger_option
- 用于指定ENCRYPTION
和/或EXECUTE AS
子句。ENCRYPTION
加密触发器的定义。EXECUTE AS
定义执行触发器的安全上下文。event_type | event_group
- 表示导致触发器触发的DDL事件,例如,CREATE_TABLE
,ALTER_TABLE
等。event_group
是一组event_type
事件,例如DDL_TABLE_EVENTS
。
触发器可以订阅一个或多个事件或事件组。
创建SQL Server DDL触发器示例
假设要捕获对数据库索引所做的所有修改,以便可以更好地监视与这些索引更改相关的数据库服务器的性能。
首先,创建一个名为index_logs
的新表来记录索引更改:
CREATE TABLE index_logs (
log_id INT IDENTITY PRIMARY KEY,
event_data XML NOT NULL,
changed_by SYSNAME NOT NULL
);
GO
接下来,创建一个DDL触发器来跟踪索引更改并将事件数据插入index_logs
表:
CREATE TRIGGER trg_index_changes
ON DATABASE
FOR
CREATE_INDEX,
ALTER_INDEX,
DROP_INDEX
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO index_logs (
event_data,
changed_by
)
VALUES (
EVENTDATA(),
USER
);
END;
GO
在触发器的主体中,使用EVENTDATA()
函数返回有关服务器或数据库事件的信息。 该函数仅在DDL或登录触发器中可用。
然后,为sales.customers
表的first_name
和last_name
列创建索引:
CREATE NONCLUSTERED INDEX nidx_fname
ON sales.customers(first_name);
GO
CREATE NONCLUSTERED INDEX nidx_lname
ON sales.customers(last_name);
GO
之后,查询index_changes
表中的数据,以检查触发器是否正确捕获了索引创建事件:
SELECT
*
FROM
index_logs;
执行上面查询语句,得到以下结果:
如果单击event_data
列的单元格,则可以按如下方式查看事件的XML数据:
<EVENT_INSTANCE>
<EventType>CREATE_INDEX</EventType>
<PostTime>2019-02-27T09:52:06.303</PostTime>
<SPID>62</SPID>
<ServerName>DESKTOP-MAXSU</ServerName>
<LoginName>DESKTOP-MAXSU\hema</LoginName>
<UserName>dbo</UserName>
<DatabaseName>bk_stores</DatabaseName>
<SchemaName>sales</SchemaName>
<ObjectName>nidx_fname</ObjectName>
<ObjectType>INDEX</ObjectType>
<TargetObjectName>customers</TargetObjectName>
<TargetObjectType>TABLE</TargetObjectType>
<TSQLCommand>
<SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE" />
<CommandText>CREATE NONCLUSTERED INDEX nidx_fname
ON sales.customers(first_name)</CommandText>
</TSQLCommand>
</EVENT_INSTANCE>
在本教程中,学习了如何创建响应一个或多个DDL事件的SQL Server DDL触发器。