zoukankan      html  css  js  c++  java
  • Sql Server 触发器

    ⒈是什么?

      触发器是一种特殊类型的存储过程,触发器主要是通过事件进行触发被自动调用执行,而存储过程可以通过存储过程的名称被调用。

      当我们对某张表进行操作(例如增删改)时会自动调用执行该表上对应的触发器。

      SQL Server 中触发器可以分为两类:DML触发器和DDL触发器,其中DDL触发器它们会影响多种数据定义语言语句而激发,这些语句有create、alter、drop语句。

        DML触发器分为:

        1、 after触发器(之后触发)

            a、 insert触发器

            b、 update触发器

            c、 delete触发器

        2、 instead of 触发器 (之前触发)

      after触发器要求只有当我们对某张表进行操作(例如增删改)时才会自动调用执行该表上对应的after触发器,且只能定义在表上。

      instead of触发器并不执行其定义的操作(insert、update、delete)而仅是执行触发器本身,既可以在表上定义instead of触发器,也可以在视图上定义。

       触发器有两张特殊的表:插入表(instered表)和删除表(deleted表)。这两张是逻辑表也是虚表。系统会在内存中创建这两张表,不会存储在数据库中。且这两张表的都是只读的,只能读取数据而不能修改数据。这两张表的结果总是与被改触发器应用的表的结构相同。当触发器完成工作后,这两张表就会自动被删除。Inserted表的数据是插入或是修改后的数据,而deleted表的数据是更新前的或是删除的数据。

    对表的操作

    Inserted逻辑表

    Deleted逻辑表

    增加记录(insert)

    存放增加的记录

    删除记录(delete)

    存放被删除的记录

    修改记录(update)

    存放更新后的记录

    存放更新前的记录

        Update数据的时候就是先删除表记录,然后增加一条记录。这样在inserted和deleted表就都有update后的数据记录了。注意的是:触发器本身就是一个事务,所以在触发器里面可以对修改数据进行一些特殊的检查。如果不满足可以利用事务回滚,撤销操作。

    ⒉创建触发器

      1.after触发器(之后触发)

        ①语法

    1 create trigger tgr_name on tableName
    2 with encryption    --加密触发器
    3 for update
    4 as
    5     sql
    6 go

        ②示例

          Ⅰinsert类型触发器

     1 if(OBJECT_ID('tgr_users_insert','tr') is not null)
     2 drop trigger tgr_users_insert
     3 go
     4 create trigger tgr_users_insert on users
     5 for insert --插入时触发
     6 as
     7     declare @id int,@username varchar(20);
     8     select @id = id,@username = username from inserted; --inserted虚拟表中存放了新插入的那条数据
     9     select concat('新用户的Id是:',@id,',新用户的用户名是:',@username);
    10 go

          Ⅱdelete类型触发器

     1 if(OBJECT_ID('tgr_users_delete','tr') is not null)
     2 drop trigger tgr_users_delete
     3 go
     4 create trigger tgr_users_delete on users
     5 for delete    --删除时触发
     6 as
     7     declare @id int,@username varchar(20);
     8     select @id = id,@username = username from deleted; --deleted虚拟表中存放了删除的那条数据
     9     select concat('删除用户的Id是:',@id,',删除用户的用户名是:',@username);
    10 go

          Ⅲupdate类型触发器

     1 if(OBJECT_ID('tgr_users_update','tr') is not null)
     2 drop trigger tgr_users_update
     3 go
     4 create trigger tgr_users_update on users
     5 for update    --更新时触发
     6 as
     7     declare @id int,@oldusername varchar(20),@newusername varchar(20);
     8     select @id = id,@oldusername = username from deleted; --deleted虚拟表中存放了更新前的那条数据
     9     select @newusername = username from inserted;    --inserted虚拟表中存放了更新后的那条数据
    10     select concat('更新用户的Id是:',@id,',更新前用户名是:',@oldusername,',更新后用户名是:',@newusername);
    11 go

          Ⅳupdate列级触发器

     1 if(OBJECT_ID('tgr_users_update_column','tr') is not null)
     2 drop trigger tgr_users_update_column
     3 go
     4 create trigger tgr_users_update_column on users
     5 for update    --更新时触发
     6 as
     7     if(update(username))
     8     begin
     9         raisError('用户名禁止修改!',16,11);
    10         rollback tran;
    11     end
    12 go

      2.instead of 触发器 (之前触发)

      instead of触发器表示并不执行其定义的操作(insert、update、delete)而仅是执行触发器本身的内容。

        ①语法

    1 create trigger tgr_name on tableName
    2 with encryption    --加密触发器
    3 instead of update
    4 as
    5     sql
    6 go

        ②示例

          Ⅰinstead of触发器

     1 if(OBJECT_ID('tgr_users_insteadof','tr') is not null)
     2 drop trigger tgr_users_insteadof
     3 go
     4 create trigger tgr_users_insteadof on users
     5 instead of delete --update, insert..
     6 as
     7     declare @id int,@username varchar(20);
     8     select @id = id , @username = username from deleted;
     9     select concat('删除用户的Id是:',@id,',删除用户的用户名是:',@username);
    10 go

          Ⅱ显示自定义消息raiserror

    1 if (OBJECT_ID('tgr_message', 'TR') is not null)
    2     drop trigger tgr_message
    3 go
    4 create trigger tgr_message on users
    5 after insert, update
    6 as 
    7     raisError('tgr_message触发器被触发', 16, 10);
    8 go

    ⒊修改触发器

    1 alter trigger tgr_message on users
    2 after delete
    3 as raisError('tgr_message触发器被触发', 16, 10);
    4 go

    ⒋启用/禁止触发器

    1 --禁用触发器
    2 disable trigger tgr_message on users;
    3 --启用触发器
    4 enable trigger tgr_message on users;

    ⒌查询触发器信息

     1 --查询已存在的触发器
     2 select * from sys.triggers;
     3 select * from sys.objects where type = 'TR';
     4 
     5 --查看触发器触发事件
     6 select te.* from sys.trigger_events te join sys.triggers t
     7 on t.object_id = te.object_id
     8 where t.parent_class = 0 and t.name = 'tgr_valid_data';
     9 
    10 --查看创建触发器语句
    11 exec sp_helptext 'tgr_message';

    ⒍附加

      1.验证数据

     1 if ((object_id('tgr_valid_data', 'TR') is not null))
     2     drop trigger tgr_valid_data
     3 go
     4 create trigger tgr_valid_data
     5 on student
     6 after insert
     7 as
     8     declare @age int,
     9             @name varchar(20);
    10     select @name = s.name, @age = s.age from inserted s;
    11     if (@age < 18)
    12     begin
    13         raisError('插入新数据的age有问题', 16, 1);
    14         rollback tran;
    15     end
    16 go

      2.操作日志

     1 if (object_id('log', 'U') is not null)
     2     drop table log
     3 go
     4 create table log(
     5     id int identity(1, 1) primary key,
     6     action varchar(20),
     7     createDate datetime default getDate()
     8 )
     9 go
    10 if (exists (select * from sys.objects where name = 'tgr_student_log'))
    11     drop trigger tgr_student_log
    12 go
    13 create trigger tgr_student_log
    14 on student
    15 after insert, update, delete
    16 as
    17     if ((exists (select 1 from inserted)) and (exists (select 1 from deleted)))
    18     begin
    19         insert into log(action) values('updated');
    20     end
    21     else if (exists (select 1 from inserted) and not exists (select 1 from deleted))
    22     begin
    23         insert into log(action) values('inserted');
    24     end
    25     else if (not exists (select 1 from inserted) and exists (select 1 from deleted))
    26     begin
    27         insert into log(action) values('deleted');
    28     end
    29 go

    原文地址,http://www.cnblogs.com/hoojo/archive/2011/07/20/2111316.html,在原作者基础上进行简化及修改。

  • 相关阅读:
    强化学习快速入门
    Spark GraphX图计算简单案例【代码实现,源码分析】
    CDA数据分析【第二章:数据收集与导入】
    CDA数据分析实务【第一章:营销决策分析概述】
    CDA数据分析【第一章:数据分析概述】
    BLAS快速入门
    Tachyon内存文件系统快速入门
    Solr新特性【4.x,5.x,6.x,7.x】
    利用Redis keyspace notification(键空间通知)实现过期提醒
    设计模式 行为型
  • 原文地址:https://www.cnblogs.com/fanqisoft/p/10780523.html
Copyright © 2011-2022 走看看