触发器(Trigger)以往仅用在特定的对象上,如数据表。当数据维护语言(DML)的Insert、Delete、Update语法针对这些对象工作时,由系统自动调用对应的触发器,而在SQL Server 2000中增加了Instead of Trigger,通过触发器来取代原本要执行的添加、修改、删除语法,且可以设置在视图上。由于Instead of Trigger是在DML语法真的改变数据写入事务日志之前触发,因此,也称为Before Trigger,而我们一般编写在事务已经发生并写入日志后的触发器,则称为After Trigger。
在SQL Server 2005之后,则扩展了触发器的应用面,加入数据定义语言(DDL)触发器功能。针对DDL语法的执行,乃至于服务器实例/数据库执行相关的存储过程、事件也可以启动触发器。可用来规范、跟踪与监控数据库架构的变化,例如新建、修改或删除数据表时,要求在什么条件下允许更改数据表;记录是谁在何时对哪些数据表的定义,做了什么样的更动。如果说DML触发器是属于数据表级别的程序,那么,DDL触发器就是属于数据库级别或是服务器级别的程序,可以针对数据库等级的语法触发DDL触发器。
你可能针对数据库等级的语法触发DDL触发器,如CREATE_TABLE;也可以是服务器等级的语法,如CREATE_LOGIN,通过在触发器内执行ROLLBACK TRANSACTION语法,能够将原来用户执行的DDL语法回滚,就如同没有执行该语法一样。与DML触发器相同的是:执行一句DDL可能同时触发多个DDL触发器,但我们无法掌控其执行顺序,所以,DDL触发器间不能有先后的依存关系。
创建DDL触发器的语法也是CREATE TRIGGER,其定义如下:
CREATE TRIGGER <trigger name>
ON { ALL SERVER | DATABASE }
[ WITH <ddl_trigger_option> [ …,n ]]
{ FOR | AFTER } { event_type | event_group } [ ,…n ]
AS { SQL [ …n ] | EXTERNAL NAME <method definition> }
在编写DDL触发器时,要指定其针对的目标是ON DATABASE或ON ALL SERVER;两者可引发触发器的事件不相同,例如,前者是定义数据库内的对象,event_type选项有CREATE_TABLE、CREATE_USER、CREATE_SCHEMA等,而后者则是以整个服务器为目标,其event_type有CREATE_LOGIN、CREATE_ENDPOINT等。你可以发现,若要列出触发器所针对的DDL语法,是在该语法间以下划线(_)连接。若不想列出event_type,系统已预先将各种DDL语法分类,例如,DDL_SERVER_SECURITY_EVENTS代表所有以服务器为目标的各类DDL语法事件,而DDL_TABLE_VEIW_EVENTS则代表了针对数据表、视图、索引与统计的DDL事件。至于有哪些event_type和event_group,以及其间树状结构的关系,你可以参照联机丛书的详细列表。
最后,在指定DDL触发器实际的内容定义时,可以是T-SQL写成的语法,也可以参照.NET来编写的组件(Assembly)内的方法。
DML的触发器在执行时,能参照SQL Server引擎所创建的deleted和inserted临时表,而DDL触发器执行时,则可以调用EVENTDATA()系统函数,以获取DDL触发器执行时相关的系统信息。该函数返回XML格式的数据,可以T-SQL的XQuery解析其内容。