DDL触发器原理

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

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 .]
--触发器名称
触发器名

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

[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 AUTHORITY\LocalService、NT AUTHORITY\NetworkService 或 NT AUTHORITY\LocalSystem。
--执行上下文的用户 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 AUTHORITY\LocalService、NT AUTHORITY\NetworkService 或 NT AUTHORITY\LocalSystem。
--执行上下文的用户 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

示例结果:

DDL触发器优缺点

优点:

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

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

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

  4、更加安全。

  5、通过使用 EVENTDATA( ) 函数,可以在触发器中使用XML信息。

缺点:

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

SQLServer之创建Transact-SQL DDL触发器的更多相关文章

  1. SQLServer之创建DML AFTER UPDATE触发器

    DML AFTER UPDATE触发器创建原理 触发器触发时,系统自动在内存中创建deleted表或inserted表,inserted表临时保存了插入或更新后的记录行,deleted表临时保存了删除 ...

  2. SQLServer之创建DML AFTER INSERT触发器

    DML AFTER INSERT触发器创建原理 触发器触发时,系统自动在内存中创建deleted表或inserted表,内存中创建的表只读,不允许修改,触发器执行完成后,自动删除. insert触发器 ...

  3. SQL Server DDL触发器运用

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 基础知识(Rudimentary Knowledge) DDL运用场景(DDL Scene) ...

  4. SQLServer之创建LOGON触发器

    LOGON触发器工作原理 登录触发器将为响应 LOGON 事件而激发存储过程. 与 SQL Server实例建立用户会话时将引发此事件. 登录触发器将在登录的身份验证阶段完成之后且用户会话实际建立之前 ...

  5. SQLServer之创建AFETER DELETE触发器

    DML AFTER DELETE触发器创建原理 触发器触发时,系统自动在内存中创建deleted表或inserted表,inserted表临时保存了插入或更新后的记录行,deleted表临时保存了删除 ...

  6. SQL Server DDL触发器

    DDL 触发器作用: DDL 触发器主要用于防止对数据库架构.视图.表.存储过程等进行的某些修改. DDL 触发器事件: DDL 触发器在创建用来监视并响应该数据库或服务器实例中的活动的事件通知时,可 ...

  7. SQLServer之创建嵌套触发器

    嵌套触发器创建规则 当触发器执行启动其他触发器的操作时,DML 和 DDL 触发器都是嵌套触发器. 这些操作都可以启动其他触发器等. DML 触发器和 DDL 触发器最多可以嵌套 32 层. 可以通过 ...

  8. 监控SQL:通过SQL Server的DDL触发器来监控数据库结构的变化(1)

    原文:监控SQL:通过SQL Server的DDL触发器来监控数据库结构的变化(1) 如果你要同步不同数据库之间的数据,首先会想到的是数据库复制技术,但如果让你同步数据库的结构,你会想到什么呢? 下面 ...

  9. SQL——登陆触发器实现限制IP

    [转载]原文地址:https://www.baidu.com/link?url=N-SM28ge21TTYky79dYk8otsjKgYCIpy-0RBSvMV25f8KSOsYczhxTOCzeNZ ...

随机推荐

  1. 【Spark篇】---Spark解决数据倾斜问题

    一.前述 数据倾斜问题是大数据中的头号问题,所以解决数据清洗尤为重要,本文只针对几个常见的应用场景做些分析 . 二.具体方法  1.使用Hive ETL预处理数据 方案适用场景: 如果导致数据倾斜的是 ...

  2. java代码之美(10)---Java8 Map中的computeIfAbsent方法

    Map中的computeIfAbsent方法 Map接口的实现类如HashMap,ConcurrentHashMap,HashTable等继承了此方法,通过此方法可以在特定需求下,让你的代码更加简洁. ...

  3. hexo配置自己的博客站点

    最近业余时间利用hexo为自己搭建一个高度自定义的个人站点,站点发布在github上,访问地址为:https://cqhaibin.github.io/.本博客简单介绍实现此站点的过程.效果图如下 构 ...

  4. asp.net core 系列 19 EFCore介绍

    一.概述 目前最新的EF Core版本是3.0,最稳定的EF Core版本是2.2.EF Core 的计划与 .NET Core以及 ASP.NET Core 版本同步.EF Core 是一个 .NE ...

  5. Python爬虫入门教程 4-100 美空网未登录图片爬取

    美空网未登录图片----简介 上一篇写的时间有点长了,接下来继续把美空网的爬虫写完,这套教程中编写的爬虫在实际的工作中可能并不能给你增加多少有价值的技术点,因为它只是一套入门的教程,老鸟你自动绕过就可 ...

  6. plsql中的procedure和function编程

    procedure:存储过程 eg:   create or replace procedure p   --这儿是和plsql的区别         is         cursor c      ...

  7. Asp.Net SignalR 集线器不使用代理的实现

    不使用生成代理JS的实现 可能有同学会觉得使用集线器很麻烦,要么引入虚拟目录,要么在生成期间生成js文件,再引入js文件进行开发.难道就没有比较清爽的方式吗?这个当然是有的,先不要(。・∀・)ノ゙嗨皮 ...

  8. C++STL模板库序列容器之List容器

    目录 一丶List容器的存储结构 二丶丶STL中list容器的使用. 一丶List容器的存储结构 list容器底层是链表结构来维护的.跟vector不一样. vector是数组维护的.拥有连续内存.所 ...

  9. 做了2个多月的设计和编码,我梳理了Flutter动态化的方案对比及最佳实现

    背景 在端上为了提升App的灵活性, 快速解决万变的业务需求,开发者们探索了多种解决方案,如PhoneGap ,React Native ,Weex等,但在Flutter生态还没有好的解决方案.未来闲 ...

  10. Docker最全教程——从理论到实战(二)

    上篇内容链接: https://www.cnblogs.com/codelove/p/10030439.html Docker和ASP.NET Core Docker 正在逐渐成为容器行业的事实标准, ...