MS SQL Server:DDL 触发器

news/2024/7/18 13:15:21 标签: 数据库

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 [url=URL]NAME[/url] < 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信息。

转载于:https://www.cnblogs.com/qanholas/archive/2012/05/10/2494643.html


http://www.niftyadmin.cn/n/1262301.html

相关文章

创意的热爱

人们都说&#xff0c;兴趣是最好的老师。柳传志说&#xff0c;紧跟时代发展&#xff0c;做最大的市场&#xff0c;雷军说&#xff0c;强制是最不人性化的&#xff0c;热爱才是永恒的。如今的移动互联网&#xff0c;开发者们是真的热爱吗&#xff1f;还是觉得前途不错&#xff0…

北京当兵叔叔

下午接到爸爸的电话&#xff0c;说三表叔的孩子今年考上大学&#xff0c;来北京读书了&#xff0c;昨天到的北京。正好北京有个当兵的老乡&#xff0c;叫我去聚聚&#xff0c;我爸爸一辈的&#xff0c;当兵的老乡2012年春节回家一次&#xff0c;很是分光。在农村混上他这样的不…

Oracle数据库快速Drop 大表

一、流程简介 1、先不直接使用Drop table命令&#xff0c;取而带之用带有REUSE STORAGE子句的Tuncate table命令。因为没有Extents要被回收&#xff0c;Trunate table命令执行很快&#xff0c;只是段的highwater mark简单的被调整到段头的block上。 2、使用带有KEEP子句的alte…

北京地铁之五道口

最近网络流行了一首神曲《地铁四惠东》&#xff0c;刚听了听&#xff0c;以为很搞笑的&#xff0c;不过怎么也笑不起来&#xff0c;唱出了我的心声&#xff0c;不只是我&#xff0c;可能是所有在北京漂泊的80后的心声。拥挤的北京&#xff0c;我想&#xff0c;我们最求的都是梦…

【转】verilog语法学习心得

这是我在查verilog的有符号数和无符号数时看到的&#xff0c;觉得很好&#xff0c;转载于此&#xff0c;共同学习--------------------------------------------------------------------------------------------------------------------------verilog语法学习心得1.数字电路…

【转贴】开源BI套件工具

开源BI套件工具小结商业&#xff22;&#xff29;套件不少&#xff0c;同样&#xff0c;开源的&#xff22;&#xff29;套件也不少&#xff0c;只是大家没有共享&#xff0c;从而很多优秀的&#xff22;&#xff29;套件没有得到利用。下面总结的开源&#xff22;&#xff29;…

1、子函数参数传递地址

#include<stdio.h> void fa(int a) /* 在函数中改变a&#xff0c;将不会带回主调函数(主调函数中的a仍是原值) */ { a; printf("在函数fa中&#xff1a;a%d\n",a); a2 } void fb(int *a) /* a为指针类型&#…