触发器

触发器是一种特殊的存储过程,一种不能被显式执行,而必须依附于一个事件的过程。只要事件发生,就会调用触发器,运行它的代码。SQL Server 支持把触发器和两种类型的事件关联:数据操做事件(如INSERT)和数据定义事件(如CREATE TABLE),和这两种事件关联的触发器分别称为DML 触发器和DDL 触发器。数据库

触发器有不少用途,包括审核数据、实施不能经过约束而实现的完整性规则、实施必定的策略,等等。服务器

能够把触发器当作是某个事务的一个组成部分,该事务包含可以触发触发器的事件。在触发器的代码中执行ROLLBACK TRAN 命令将会致使触发器内发生的全部更改,以及和触发器关联的事务中进行的全部更改都发生回滚。函数

在SQL Server中,触发器是按照语句触发的,而不是按照被修改的行而触发的。post

1. DML触发器事件

SQL Server 支持两种DML触发器:AFTER 触发器和INSTEAD OF 触发器。AFTER 触发器是在与之关联的事件完成后才触发的,只能在持久化的表上定义这种触发器。INSTEAD OF 触发器的触发是为了代替与之关联的事件操做,能够在持久化的表或视图上定义这种类型的触发器。事务

在触发器代码中,能够访问称为inserted和deleted的两个表,它们包含致使触发器触发修改操做而影响的记录行。inserted 表包含当执行INSERT和UPDATE 语句时受影响行的新数据的镜像。deleted表则包含当执行DELETE和UPDATE语句时受影响行的旧数据的镜像。对于INSTEAD OF 触发器,inserted和deleted表包含致使触发器触发的修改操做打算要影响的行。作用域

CREATE TRIGGER trg_T1_insert_audit ON dbo.T1 AFTER INSERTget

ASit

SET NOCOUNT ON;event

INSERT INTO dbo.T1_Audit(keycol,datacol)

  SELECT keycol,datacol FROM inserted;

GO

2. DDL 触发器

SQL Server 2005 引入了对DDL 触发器的支持,它们能够用于在数据库中执行审核、加强策略、变化管理等任务。

SQL Server 支持在两个做用域内建立DDL 触发器(数据库做用域和服务器做用域),这要取决于事件的做用域。例如,对于数据库做用域的事件(如CREATE TABLE),能够建立数据库做用域内的触发器;对于具备服务器做用域的事件(如CREATE DATABASE),能够建立服务器做用域内的触发器。SQL Server只支持AFTER类型的DDL触发器,而不支持BEFORE或INSTEAD OF 类型的DDL触发器。

在触发器中,经过查询EVENTDATA函数(该函数将事件信息做为XML值返回),能够获取关于致使触发器触发的事件信息。再用XQuery表达式从XML 值中提取各类事件属性,如提交时间、事件类型、登陆名称等。

在数据库上经过事件组DDL_DATABASE_LEVEL_EVENTS 来建立审核触发器trg_audit_ddl_events,这个事件组表明数据库级上的全部DDL事件:

 CREATE TRIGGER trg_audit_ddl_events

  ON DATABASE FOR DDL_DATABASE_LEVEL_EVENTS

AS

SET NOCOUNT ON;

DECLARE @eventdata AS XML;

SET @eventdata=eventdata();

INSERT INTO dbo.AuditDDLEvents(

  posttime,eventtype,loginname,schemaname,objectname,targetobjectname,eventdate)

  VALUES(

    @eventdata.value('(/EVENT_INSTANCE/PostTime)[1]',     'VARCHAR(23)'),

    @eventdata.value('(/EVENT_INSTANCE/EventType)[1]',     'sysname'),

    @eventdata.value('(/EVENT_INSTANCE/LoginName)[1]',     'sysname'),

    @eventdata.value('(/EVENT_INSTANCE/SchemaName)[1]',     'sysname'),

    @eventdata.value('(/EVENT_INSTANCE/ObjectName)[1]',     'sysname'),

    @eventdata.value('(/EVENT_INSTANCE/TargetObjectName)[1]',     'sysname'),

    @eventdata);

GO

相关文章
相关标签/搜索