首先明确什么是DDL触发器?DDL触发器和普通的表触发器有什么区别?
1、普通的触发器的绑定对象为表,它定义了当一个表发生了【增】、【删】、【改】的DML语句时,默认执行的sql语句。
这里我们称之为表触发器,表触发器的用途很多,可以用作维持数据一致性的级联同步,和数据一致性,保证的数据的完整性;另外还通常被用作创建日志表使用。通过所定义的语句,当一个表发生增删改动作的时候,记录下每次DML语句的日志情况。
2、而DDL触发器的绑定对象是某个数据库,顾名思义,它是隶属于某个数据库的触发器,它定义了当一个数据库内的对象发生了 【修改】、【创建】、【删除】的执行的执行的sql语句。
这里我们称之为数据库触发器。(数据库对象:【表】、【视图】、【函数】、【触发器】、【存储过程】等)
使用DDL触发器,我们可以实现对数据库中的相关对象的变更历史进行记录,并进行管控
例如:对于一个事务性系统而言(例如ERP),可能会有很多开发人员在数据库上进行进行编程,由于需求变更、版本更替等一系列原因,我们会不停的对某个存储过程进行多次的修改并投入使用,而通常存储过程是无法像C#,JAVA等编程语言一样,可以进行代码管理,并有对应的版本更替,版本回滚等。但是当我们需要查看这个存储过程经历了哪些变动,每次修改了什么地方时,我们就无法系统性进行管理和查看(当然,可以人为的记录在excel等相关文档中)
这个时候就可以使用DDL触发器对这些相应对象的变更进行日志记录,并相关管控
下面是设置为某个数据库设置触发器变更日志记录的DDL语句
CREATE TRIGGER DLL_TRIGGER_CREATE_ALTER_DROP ON DATABASE
FOR CREATE_TRIGGER, DROP_TRIGGER, ALTER_TRIGGER
AS
/*
本触发器只针对触发器的增删改,进行记录触发器的相关信息
*/
IF OBJECT_ID('dbo.ddl_trigger_log', 'U') = NULL
CREATE TABLE dbo.ddl_trigger_log
(
rowid INT IDENTITY ,
EventType VARCHAR(20) ,
PostTime DATETIME ,
SPID INT ,
ServerName VARCHAR(255) ,
LoginName VARCHAR(255) ,
DatabaseName VARCHAR(255) ,
UserName VARCHAR(255),
SchemaName VARCHAR(20) ,
ObjectName VARCHAR(255) ,
ObjectType VARCHAR(20) ,
CommandText NVARCHAR(MAX) ,
remark NVARCHAR(MAX) ,
commandtext_check INT
);
DECLARE @EeventType VARCHAR(20),
@PostTime DATETIME,
@SPID INT,
@ServerName VARCHAR(255),
@LoginName VARCHAR(255),
@DatabaseName VARCHAR(255),
@UserName VARCHAR(255),
@SchemaName VARCHAR(255),
@ObjectName VARCHAR(255),
@ObjectType VARCHAR(20),
@CommandText NVARCHAR(MAX),
@Remarks NVARCHAR(MAX),
@Commandtest_check INT
SET @EeventType=EVENTDATA().value('(/EVENT_INSTANCE/EventType)[1]','VARCHAR(20)')
SET @PostTime=EVENTDATA().value('(/EVENT_INSTANCE/PostTime)[1]','DATETIME')
SET @SPID=EVENTDATA().value('(/EVENT_INSTANCE/SPID)[1]','INT')
SET @ServerName=EVENTDATA().value('(/EVENT_INSTANCE/ServerName)[1]','VARCHAR(255)')
SET @LoginName=EVENTDATA().value('(/EVENT_INSTANCE/LoginName)[1]','VARCHAR(255)')
SET @DatabaseName=EVENTDATA().value('(/EVENT_INSTANCE/LoginName)[1]','VARCHAR(255)')
SET @UserName=EVENTDATA().value('(EVENT_INSTANCE/UserName)[1]','VARCHAR(255)')
SET @SchemaName=EVENTDATA().value('(EVENT_INSTANCE/SchemaName)[1]','VARCHAR(255)')
SET @ObjectName=EVENTDATA().value('(EVENT_INSTANCE/ObjectName)[1]','VARCHAR(255)')
SET @ObjectType=EVENTDATA().value('(EVENT_INSTANCE/ObjectType)[1]','VARCHAR(255)')
SET @CommandText=EVENTDATA().value('(EVENT_INSTANCE/TSQLCommand/CommandText)[1]','NVARCHAR(MAX)')
INSERT INTO dbo.ddl_trigger_log
( EventType ,
PostTime ,
SPID ,
ServerName ,
LoginName ,
DatabaseName ,
UserName ,
SchemaName ,
ObjectName ,
ObjectType ,
CommandText ,
remark ,
commandtext_check
)
SELECT @EeventType ,
@PostTime ,
@SPID ,
@ServerName ,
@LoginName ,
@DatabaseName ,
@UserName ,
@SchemaName ,
@ObjectName ,
@ObjectType ,
@CommandText ,
'' ,
0;
执行了脚本之后,在该数据库上发生了任何关于触发器的ALTER、DROP、CREATE 语句都会记录在日志表中
详细的相关信息都可以通过日志表进行查看