SQLServer之建立Transact-SQL DDL触发器

DDL触发器原理

DDL 触发器用于响应各类数据定义语言 (DDL) 事件。 这些事件主要与以关键字 CREATE、ALTER、DROP、GRANT、DENY、REVOKE 或 UPDATE STATISTICS 开头的 Transact-SQL 语句对应。 执行 DDL 式操做的系统存储过程也能够激发 DDL 触发器。sql

DDL触发器在数据库或模式级运行,DDL触发器一般用于记录数据库的修改过程和监控数据库中的重要事件。数据库

DDL触发器建立

语法:

--声明数据库引用
use 数据库名;
go安全

--判断是否存在要建立的触发器,若是存在则删除
if exists(select * from sys.triggers where name=触发器名)
drop trigger 触发器名 on { database | all server };
go服务器

--建立触发器
create架构

--触发器标识符
trigger函数

--DML 触发器所属架构的名称。 DML 触发器的做用域是为其建立该触发器的表或视图的架构。 不能为 DDL 或登陆触发器指定 schema_name。
--[ schema_name .]
--触发器名称
触发器名spa

--ALL SERVER
--适用范围: SQL Server 2008 到 SQL Server 2017。
--将 DDL 或登陆触发器的做用域应用于当前服务器。 若是指定了此参数,则只要当前服务器中的任何位置出现 event_type 或 event_group,就会激发该触发器。
--database
--将 DDL 触发器的做用域应用于当前数据库。 若是指定了此参数,则只要当前数据库中出现 event_type 或 event_group,就会激发该触发器。
on { database | all server }server

[with]对象

--适用范围: SQL Server 2008 到 SQL Server 2017。
--对 CREATE TRIGGER 语句的文本进行模糊处理。 使用 WITH ENCRYPTION 能够防止将触发器做为 SQL Server 复制的一部分进行发布。 不能为 CLR 触发器指定 WITH ENCRYPTION。
encryptionblog

--EXECUTE AS Clause
--{ EXEC | EXECUTE } AS { SELF | OWNER | 'user_name' }
--CALLER
--指定模块内的语句在模块调用方的上下文中执行。 执行模块的用户不只必须对模块自己拥有适当的权限,还要对模块引用的任何数据库对象拥有适当权限。
--CALLER 是除队列外的全部模块的默认值,与 SQL Server 2005 行为相同。
--CALLER 不能在 CREATE QUEUE 或 ALTER QUEUE 语句中指定。
--SELF
--EXECUTE AS SELF 与 EXECUTE AS user_name 等价,其中指定用户是建立或更改模块的用户。 建立或更改模块的用户的实际用户 ID 存储在 sys.sql_modules 或 sys.service_queues 目录视图的 execute_as_principal_id 列中。
--SELF 是队列的默认值。
--OWNER
--指定模块内的语句在模块的当前全部者上下文中执行。 若是模块没有指定的全部者,则使用模块架构的全部者。 不能为 DDL 或登陆触发器指定 OWNER。
--' user_name '
--指定模块内的语句在 user_name 指定的用户的上下文中执行。 将根据 user_name 来验证对模块内任意对象的权限。 不能为具备服务器做用域的 DDL 触发器或登陆触发器指定 user_name。 请改用 login_name。
--user_name 必须存在于当前数据库中,而且必须是单一实例账户。 user_name 不能为组、角色、证书、密钥或内置账户,如 NT AUTHORITYLocalService、NT AUTHORITYNetworkService 或 NT AUTHORITYLocalSystem。
--执行上下文的用户 ID 存储在元数据中,能够在 sys.sql_modules 或 sys.assembly_modules 目录视图的 execute_as_principal_id 列查看。
[execute as caller]

--FOR | AFTER
--AFTER 指定 DML 触发器仅在触发 SQL 语句中指定的全部操做都已成功执行时才被触发。 全部的引用级联操做和约束检查也必须在激发此触发器以前成功完成。
--若是仅指定 FOR 关键字,则 AFTER 为默认值。
--不能对视图定义 AFTER 触发器。
{ for | after }

--event_type
--执行以后将致使激发 DDL 触发器的 Transact-SQL 语言事件的名称。 DDL 事件中列出了 DDL 触发器的有效事件。
--event_group
--预约义的 Transact-SQL 语言事件分组的名称。 执行任何属于 event_group 的 Transact-SQL 语言事件以后,都将激发 DDL 触发器。 DDL 事件组中列出了 DDL 触发器的有效事件组。
--CREATE TRIGGER 运行完成后,event_group 还将充当宏,将它涉及的事件类型添加到 sys.trigger_events 目录视图中。
{ event_type | event_group }
as
begin
sql_statement;
end
go

示例:

--声明数据库引用
use testss;
go

--判断是否存在要建立的触发器,若是存在则删除
if exists(select * from sys.triggers where name='ddltri')
drop trigger ddltri on database;
go

--建立触发器
create

--触发器标识符
trigger

--DML 触发器所属架构的名称。 DML 触发器的做用域是为其建立该触发器的表或视图的架构。 不能为 DDL 或登陆触发器指定 schema_name。
--[ schema_name .]
--触发器名称
ddltri

--ALL SERVER
--适用范围: SQL Server 2008 到 SQL Server 2017。
--将 DDL 或登陆触发器的做用域应用于当前服务器。 若是指定了此参数,则只要当前服务器中的任何位置出现 event_type 或 event_group,就会激发该触发器。
--database
--将 DDL 触发器的做用域应用于当前数据库。 若是指定了此参数,则只要当前数据库中出现 event_type 或 event_group,就会激发该触发器。
on database

with

--适用范围: SQL Server 2008 到 SQL Server 2017。
--对 CREATE TRIGGER 语句的文本进行模糊处理。 使用 WITH ENCRYPTION 能够防止将触发器做为 SQL Server 复制的一部分进行发布。 不能为 CLR 触发器指定 WITH ENCRYPTION。
encryption,

--EXECUTE AS Clause
--{ EXEC | EXECUTE } AS { SELF | OWNER | 'user_name' }
--CALLER
--指定模块内的语句在模块调用方的上下文中执行。 执行模块的用户不只必须对模块自己拥有适当的权限,还要对模块引用的任何数据库对象拥有适当权限。
--CALLER 是除队列外的全部模块的默认值,与 SQL Server 2005 行为相同。
--CALLER 不能在 CREATE QUEUE 或 ALTER QUEUE 语句中指定。
--SELF
--EXECUTE AS SELF 与 EXECUTE AS user_name 等价,其中指定用户是建立或更改模块的用户。 建立或更改模块的用户的实际用户 ID 存储在 sys.sql_modules 或 sys.service_queues 目录视图的 execute_as_principal_id 列中。
--SELF 是队列的默认值。
--OWNER
--指定模块内的语句在模块的当前全部者上下文中执行。 若是模块没有指定的全部者,则使用模块架构的全部者。 不能为 DDL 或登陆触发器指定 OWNER。
--' user_name '
--指定模块内的语句在 user_name 指定的用户的上下文中执行。 将根据 user_name 来验证对模块内任意对象的权限。 不能为具备服务器做用域的 DDL 触发器或登陆触发器指定 user_name。 请改用 login_name。
--user_name 必须存在于当前数据库中,而且必须是单一实例账户。 user_name 不能为组、角色、证书、密钥或内置账户,如 NT AUTHORITYLocalService、NT AUTHORITYNetworkService 或 NT AUTHORITYLocalSystem。
--执行上下文的用户 ID 存储在元数据中,能够在 sys.sql_modules 或 sys.assembly_modules 目录视图的 execute_as_principal_id 列查看。
execute as caller

--FOR | AFTER
--AFTER 指定 DML 触发器仅在触发 SQL 语句中指定的全部操做都已成功执行时才被触发。 全部的引用级联操做和约束检查也必须在激发此触发器以前成功完成。
--若是仅指定 FOR 关键字,则 AFTER 为默认值。
--不能对视图定义 AFTER 触发器。
for

--event_type
--执行以后将致使激发 DDL 触发器的 Transact-SQL 语言事件的名称。 DDL 事件中列出了 DDL 触发器的有效事件。
--event_group
--预约义的 Transact-SQL 语言事件分组的名称。 执行任何属于 event_group 的 Transact-SQL 语言事件以后,都将激发 DDL 触发器。 DDL 事件组中列出了 DDL 触发器的有效事件组。
--CREATE TRIGGER 运行完成后,event_group 还将充当宏,将它涉及的事件类型添加到 sys.trigger_events 目录视图中。
create_table,alter_table,drop_table
as
begin
print('你触发了ddl触发器');
end
go

示例结果:

clipboard.png

DDL触发器优缺点

优势:

  一、记录数据库的修改过程。

  二、监控数据库中的重要事件。

  三、防止对数据库架构执行恶意更改。

  四、更加安全。

  五、经过使用 EVENTDATA( ) 函数,能够在触发器中使用XML信息。

缺点:

  一、滥用会形成数据库及应用程序的维护困难。

相关文章
相关标签/搜索