• 关于MSDN《了解 DML 触发器》


     

    这是SQLServer基础知识方面的一片文章,msdn中有关触发器的介绍文章
    <<
    了解 DML 触发器>>
    http://msdn.microsoft.com/zh-cn/library/ms178110.aspx

    其中有一段描述

    DML 触发器在以下方面非常有用:

    • DML 触发器可通过数据库中的相关表实现级联更改。不过,通过级联引用完整性约束可以更有效地进行这些更改。
    • DML 触发器可以防止恶意或错误的 INSERTUPDATE 以及 DELETE 操作,并强制执行比 CHECK 约束定义的限制更为复杂的其他限制。
      CHECK 约束不同,DML 触发器可以引用其他表中的列。例如,触发器可以使用另一个表中的 SELECT 比较插入或更新的数据,以及执行其他操作,如修改数据或显示用户定义错误信息。
    • DML 触发器可以评估数据修改前后表的状态,并根据该差异采取措施。
    • 一个表中的多个同类 DML 触发器(INSERTUPDATE DELETE)允许采取多个不同的操作来响应同一个修改语句。

    于初学者往往会滥用触发器导致数据库管理混乱,触发器是把双刃剑,慎用.从上面的描述可以看出来,ms还是倾向于在用普通约束或其他sql本身无法解决的 时候才推荐使用触发器.我个人认为在类似他列举的13这两条,在具备条件的情况下应该也少用触发器,而是在程序中通过事务控制实现.

    这里也不再讨论滥用的这个问题,而是对以上ms推荐的四种场景来举例讨论具体应用情况.

    1.
    第一个场景主要是说明某表数据变动,其他依赖表项能同步反映.下面测试语句可以直接运行.



    /******************************************

    DML 触发器可通过数据库中的相关表实现级联更改

    *******************************************/

    --测试用例:同步张同构表

    --创建测试表

    create table a(id int ,name varchar(10))

    create table b(id int ,name varchar(10))

    go

    --建立触发器

    create trigger trg_test

    on a

    for insert,update,delete

    as

    begin

        if exists (select 1 from deleted)

           delete from b where id in(select id from deleted)

        if exists (select 1 from inserted)

           insert into b select * from inserted

    end

    go

    --测试insert同步

    insert into a select 1,'jinjazz'

    select * from b

    --测试update同步

    update a set name='剪刀' where id=1

    select * from b

    --测试delete同步

    delete from a

    select * from b

    go

    drop table a

    drop table b


    2.第二个场景是一个复杂的约束检查,这里的约束采用黑名单模式,分普通触发器和instead of触发器两个测试用例.instead of顾名思义,就是代替(忽略)了insert之类的操作,是前触发的.


    /*************************************************************

    DML 触发器可以防止恶意或错误的INSERTUPDATE 以及DELETE 操作

    *************************************************************/

    --测试用例:黑名单和回滚

    --创建测试表

    create table a(id int ,name varchar(10))

    create table b(name varchar(10))

    insert into b select 'jinjazz'

    go

    --建立触发器

    create trigger trg_test

    on a

    for insert

    as

    begin

        if exists(select 1 from inserted where name in(select name from b))

           rollback

    end

    go

    --测试插入,此处会有中断信息请逐条运行

    insert into a select 1,'jinjazz'

    select * from a

    drop table a

    drop table b


    /*************************************************************

    DML 触发器可以防止恶意或错误的INSERTUPDATE 以及DELETE 操作

    *************************************************************/

    --测试用例:插入前判断黑名单

    --创建测试表

    create table a(id int ,name varchar(10))

    create table b(name varchar(10))

    insert into b select 'jinjazz'

    go

     

    create  trigger trg_test1

    on a

    instead of insert

    as

    begin

        if exists(select 1 from inserted where name in(select name from b))

           print '路过,什么也不做'

        else

           insert into a select * from inserted

    end

    go

    insert into a select 1,'jinjazz'

    select * from a

     

    drop table a

    drop table b

     

    3.第三个场景是记录数据变化过程的,因为有inserted表和deleted表,他还是有一定的性能优势的.

    /*************************************************************

    DML 触发器可以评估数据修改前后表的状态,并根据该差异采取措施.

    *************************************************************/

     

    --测试用例:差值记录

    --创建测试表

    create table  a(id int, value int)

    create table b(id int,valuechanged int)

    go

    create trigger trg_test

    on a for update

    as

    begin

        declare @v1 int

        declare @v2 int

        declare @id int

        select @v1=value from deleted

        select @id=id,@v2=value from inserted

        insert into b select @id,@v2-@v1

    end

    go

    insert into a select 1,7

    update a set value=10 where id=1

    update a set value=20 where id=1

    update a set value=8 where id=1

     

    select * from b

     

    go

    drop table a

    drop table b


    4.第四个描述如果我理解的不错的话,应该是说明一个表可以挂多个同类型触发器,这样执行一条sql dml语句就会执行多个触发器.

     

    /**********************************************************************

    一个表中的多个同类DML 触发器允许采取多个不同的操作来响应同一个修改语句

    **********************************************************************/

    create table  a(id int, name varchar(10))

    go

    create trigger trg_test

    on a

    for insert

    as

    begin

        print 'test'

    end

    go

    create trigger trg_test1

    on a

    for insert

    as

    begin

        print 'test1'

    end

    go

    insert into a select 1,'jinjazz'

     

    drop table a



  • 相关阅读:
    在ASP.NET中使用FusionCharts图表
    IE 输入baidu就死掉
    以WebServices方式上传图片
    GUID System.Guid .
    记录一个静态类的静态属性
    [转]通用分页存储过程
    如何解决“呈现控件时出错”的问题
    C#中调用SQL存储过程(带输入输出参数的例子)
    Rose实例:构造银行业务模型[转]
    Mylove net 我们手里的金钱只是保持自由的一种工具!卢梭
  • 原文地址:https://www.cnblogs.com/cl1024cl/p/6204874.html
Copyright © 2020-2023  润新知