设为首页 收藏本站
查看: 764|回复: 0

[经验分享] MS SQL Server:DDL 触发器....

[复制链接]

尚未签到

发表于 2016-11-1 08:46:47 | 显示全部楼层 |阅读模式
MS SQL Server:DDL 触发器
DDL 触发器 (本文转摘于网络)

1. DDL Trigger 触发事件总汇:
在创建用来监视并响应该数据库或服务器实例中的活动的事件通知时,可以指定相应事件类型或事件组。

DDL_DATABASE_LEVEL_EVENTS 包括:
  DDL_TRIGGER_EVENTS,
  DDL_FUNCTION_EVENTS,
  DDL_SYNONYM_EVENTS,
  DDL_SSB_EVENTS,
  DDL_DATABASE_SECURITY_EVENTS,
  DDL_EVENT_NOTIFICATION_EVENTS,
  DDL_PROCEDURE_EVENTS,
  DDL_TABLE_VIEW_EVENTS,
  DDL_TYPE_EVENTS,
  DDL_XML_SCHEMA_COLLECTION_EVENTS,
  DDL_PARTITION_EVENTS,
  DDL_ASSEMBLY_EVENTS

DDL_SERVER_LEVEL_EVENTS 包括:
  DDL_DATABASE_EVENTS,
  DROP_DATABASE,
  DDL_ENDPOINT_EVENTS,
  CREATE_DATABASE,
  DDL_SERVER_SECURITY_EVENTS,
  ALTER_DATABASE


2. DDL Trigger 语法

-- Trigger on a CREATE, ALTER, DROP, GRANT, DENY, REVOKE, or UPDATE
-- STATISTICS statement (DDL Trigger)
CREATE TRIGGER trigger_name
ON { ALL SERVER | DATABASE }
[ WITH <ddl_trigger_option> [ ,...n ] ]
{ FOR | AFTER } { event_type | event_group } [ ,...n ]
AS { sql_statement[ ; ] [ ,...n ] | EXTERNAL NAME < method specifier >[ ; ] }

<ddl_trigger_option> ::=
  [ ENCRYPTION ]
  [ EXECUTE AS Clause ]

<method_specifier> ::=
  assembly_name.class_name.method_name



-- Trigger on a LOGON event (Logon Trigger)
CREATE TRIGGER trigger_name
ON ALL SERVER
[ WITH <logon_trigger_option> [ ,...n ] ]
{ FOR | AFTER } LOGON
AS { sql_statement[ ; ] [ ,...n ] | EXTERNAL NAME <method specifier>[ ; ] }
<logon_trigger_option> ::=
  [ ENCRYPTION ]
  [ EXECUTE AS Clause ]

<method_specifier> ::=
  assembly_name.class_name.method_name



3. 删除DDL trigger
从系统中删除DDL触发器不能像删除其他对象那样可以简单的通过 DROP object_type object_name 来实现。对于 DDL 触发器,需要在触发器的作用钱使用一个前缀。

语法:
DROP TRIGGER trigger_name ON { DATABASE | ALL SERVER}


4. EVENTDATA( ) 函数
当事件触发时,尽管这里没有 INSERTED 和 DELETED 表提供检查什么被改变了,但可以使用名为 EVENTDATA( ) 的函数。该函数返回一个 XML 数据类型,其中包含触发器的事件信息。XML数据的基本语法如下,不过,根据被触发的时间不同,函数中的内容也会有所不同。
<SQLInstance>
  <PostTime>date-time</PostTime>
  <SPID>spid</SPID>
  <ComputerName>name</ComputerName>
</SQLInstance>


数据库级别事件具有下面的基本语法,这同以前显示的语法基本语法不同:
<SQLInstance>
  <PostTime>date-time</PostTime>
  <SPID>spid</SPID>
  <ComputerName>name</ComputerName>
  <DatabasesName>name</DatabasesName>
  <UserName>name</UserName>
  <LoginName>name</LoginName>
</SQLInstance>


XML元素 描述如下:
  PostTime:事件触发的日期和时间Ø
Ø SPID:指派到导致触发器被触发的代码上的SQLServer进程ID
  ComputerName:导致事件被触发的计算机名称Ø
Ø DatabasesName:导致事件被触发的数据库名称
  UserName: 导致事件被触发的用户名称Ø
Ø LoginName: 导致事件被触发的用户登录名

实例:如果是工作时间,则不允许修改任何存储过程,否则回滚
DROP TRIGGER TEST_DDL_TRIGGER ON DATABASE
GO
CREATE TRIGGER TEST_DDL_TRIGGER
ON DATABASE
FOR CREATE_PROCEDURE, ALTER_PROCEDURE, DROP_PROCEDURE
AS
IF DATEPART(hour, GETDATE()) >=9 AND DATEPART(hour, GETDATE()) <= 17
BEGIN
  DECLARE @Message nvarchar(max)
  SELECT @Message =
      'Completing work during core hours. Trying to release -'
      + EVENTDATA().value(
      '(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]',
      'nvarchar(max)')

  RAISERROR(@Message, 16, 1)
  ROLLBACK
END
GO


例2:创建一个数据库中发生任何行为时都被触发的触发器:
DROP TRIGGER TEST_DDL_TRIGGER_3 ON DATABASE
GO
CREATE TRIGGER TEST_DDL_TRIGGER_3
ON DATABASE
FOR DDL_DATABASE_LEVEL_EVENTS
AS
  SELECT EVENTDATA()
GO

接下来创建一个存储过程,来查看返回的XML数据:
CREATE PROCEDURE TEST_TRIGGER_UTIL
AS
  SELECT 'Hello all ~'
GO

返回的 XML 数据如下(经过格式化后):
<EVENT_INSTANCE>
  <EventType>CREATE_PROCEDURE</EventType>
  <PostTime>2008-03-31T13:53:35.397</PostTime>
  <SPID>56</SPID><ServerName>ZHANGZJSQLEXPRESS</ServerName>
  <LoginName>ZHANGZJDavid_Zhang</LoginName>
  <UserName>dbo</UserName>
  <DatabaseName>MySQLServer</DatabaseName>
  <SchemaName>dbo</SchemaName>
  <ObjectName>TEST_TRIGGER_UTIL</ObjectName>
  <ObjectType>PROCEDURE</ObjectType>
  <TSQLCommand>
  <SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE" />
  <CommandText>
    CREATE PROCEDURE TEST_TRIGGER_UTIL
    AS
    SELECT 'Hello all ~'
  </CommandText>
  </TSQLCommand>
</EVENT_INSTANCE>

5. 小结
DML 触发器可以看作是一种特殊的存储过程,可以版主系统保持其完整性,在系统中进行级联更新或强行业务规则。通过 INSERTED 和 DELETED 两个表,我们可以检索哪些列被更新了。DML触发器的本质就是当这两个表中发生数据修改时自动运行的存储过程。

DDL 触发器的构建主要是为了安全,或者根据部门的需求对系统所进行的变更进行通报。通过使用 EVENTDATA( ) 函数,可以在触发器中使用XML信息。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-294055-1-1.html 上篇帖子: 连接Sql Server 查询、插入数据 下篇帖子: Sql Server 存储过程实例讲解
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表