SQL Sever创建和使用触发器

触发器的概念

触发器是一类特殊的存储过程
它作为一个对象存储在数据库中。
触发器为数据库管理人员和程序开发人员提供了一种保证数据完整性的方法。
触发器是定义在特定的表或视图上的。
当有操作影响到触发器保护的数据时,例如,数据表发生了INSERT、UPDATE或DELETE操作时,如果该表有对应的触发器,这个触发器就会自动激活执行

触发器的功能

触发器是针对数据库和数据表的特殊存储过程,它在指定的表中的数据发生改变时自动生效,并可以包含复杂的T-SQL语句,表达复杂的表间完整性要求,处理各种复杂的操作。
(SQL Server 2008提供了两种方法来保证数据完整性:约束和触发器)
SQL Server将触发器和触发它的语句作为可在触发器内回滚的单个事务对待,如果检测到严重错误,则整个事务即自动回滚恢复到原来的状态

触发器的类型

在SQL Server 2008中,根据激活触发器执行的T-SQL语句类型,可以把触发器分为两类:
一类是DML触发器(数据操作触发器),
一类是DDL触发器(数据定义触发器)。

1. DML触发器(数据操作触发器)

DML触发器是当数据库服务器中发生数据操作语言DML事件时执行的特殊存储过程,如INSERT、UPDATE或DELETE等。
DML触发器根据其引发的时机不同又可以分为两种类型:

  • AFTER触发器
  • INSTEAD OF触发器

1.1 AFTER触发器

在执行了INSERT、UPDATE或DELETE语句操作之后执行AFTER触发器。
它主要用于记录变更后的处理
一旦发现错误,也可使用ROLLBACK TRANSACTION语句来回滚本次的操作

1.2 INSTEAD OF触发器

这类触发器一般是用来取代原本要进行的操作,是在记录变更之前发生的,它并不去执行原来的SQL语句里的操作,而是去执行触发器本身所定义的操作。

2. DDL触发器

DDL触发器是当数据库服务器中发生数据定义语言DDL事件时执行的特殊存储过程,如CREATE、ALTER等。
DDL触发器一般用于执行数据库中的管理任务,如审核和规范数据库操作,防止数据库表结构被修改等。

inserted表和deleted表

每个触发器有两个特殊的表:inserted表和deleted表。
这两个表建在数据库服务器的内存中,是由系统管理的逻辑表,而不是真正存储在数据库中的物理表。
对于这两个表,用户只有读取的权限,没有修改的权限。
这两个表的结构与触发器所在的表的结构是完全一致的。
当触发器的工作完成之后,这两个表也将从内存中删除

inserted表

对于插入记录操作来说,inserted表里存储的是要插入的数据
对于更新记录操作来说,inserted表里存放的是要更新的记录(要写入的数据)

deleted表

对于删除记录操作来说,deleted表里存放的是被删除的旧记录
对于更新记录操作来说,deleted表里存放的是更新前的记录(被删除的旧记录)

故:
进行INSERT操作时,只影响inserted表;
进行DELETE操作时,只影响deleted表;
进行UPDATE操作时,既影响inserted表也影响到deleted表。

T-SQL语句创建触发器

触发器与表(视图)是紧密相关的。
在创建触发器时,需要指定触发器的名称、包含触发器的、引发触发器的条件以及当触发器启动后要执行的语句等内容。

CREATE  TRIGGER  trigger_name
ON  { table_name | view_name }
{[FOR | AFTER] | INSTEAD OF}
{[INSERT ] [,] [UPDATE] [,] [DELETE]}
[WITH  ENCRYPTION]
AS
    SQL_statement

(1)trigger_name:触发器名称。
(2)table|view:触发器表(或触发器视图)名称,指出被触发者
(3)FOR|AFTER| INSTEAD OF:FOR与AFTER均指定为AFTER触发器,INSTEAD OF指定为INSTEAD OF触发器。该项指出了触发时机(即何时触发)。
(4)INSERT 指定了为INSERT触发器,UPDATE指定为UPDATE触发器, DELETE指定为DELETE触发器。该项指出了何种操作触发
(5)WITH ENCRYPTION:对CREATE TRIGGER语句的文本进行加密。防止将触发器作为 SQL Server 复制的一部分进行发布。
(6)AS 引导触发器的主体。
(7)SQL_statement指出触发器完成的功能


注意,创建触发器有下列限制:
(1)CREATE TRIGGER必须是批处理中的第一条语句,并且只能应用于
一个表(视图)
(2)触发器只能在
当前数据库中创建。
(3)
不能在视图上定义 AFTER 触发器。在表或视图上,每个 INSERT、UPDATE 或 DELETE 语句最多可以定义一个 INSTEAD OF 触发器。
(4)创建DML触发器的权限默认分配给表的所有者,且不能将该权限转给其他用户。
(5)在触发器内可以指定任意的 SET 语句。选择的 SET 选项在触发器执行期间保持有效,然后恢复为原来的设置。


创建INSERT触发器

  1. 创建触发器tr1_student ,为student新增学生后,统计新增的人数并输出。
CREATE TRIGGER tr1_student  ON student
      AFTER  INSERT    
AS
    DECLARE    @Scount int;
    SELECT    @Scount=COUNT(*)     FROM  INSERTED;
    PRINT @Scount;

触发该触发器的语句 :

 INSERT INTO student 
  VALUES (  ……  )  /*可多行*/
                 (  ……  ) 
                    … ;

创建INSERT触发器

设c001、c002是每个学生的必修课,创建触发器tr2_student ,新增一个学生后,增加其选课信息。

CREATE TRIGGER tr2_student  ON student
    AFTER  INSERT    
AS
    DECLARE    @Snum CHAR(8);
    SELECT    @Snum=Sno   FROM INSERTED;    
    INSERT INTO sc  
       VALUES ( @Snum,’c001’,null ), ( @Snum,’c002’,null );

触发该触发器的语句 :

INSERT INTO student  VALUES(  ……  );  /*只能一行*/

创建DELETED触发器

  1. 创建触发器tr1_sc ,删除c001的选课信息,统计其记录数并输出。(即删除了的记录个数)
CREATE TRIGGER tr1_sc  ON sc
    AFTER  DELETE   
AS
    DECLARE    @Scount int;
    SELECT    @Scount=COUNT(*)   FROM DELETED;
    PRINT ‘从SC中删除了’+cast(@Scount as char(4))+’行。’;

触发该触发器的语句 :

DELETE FROM SC WHERE Cno=‘c001’;

创建UPDATE触发器

UPDATE触发器在用户发出UPDATE语句后触发执行。
该触发器合并了DELETE触发器和INSERT触发器的作用。
在用户执行了UPDATE语句后,原来的数据行从基本表中删除,但保存在DELETED表中,同时基本表更新后的新数据行也在INSERTED表中保存了一个副本。
可利用DELETED表和INSERTED表,获取更新前后的数据行,完成比较操作。

设有表SC1(Sno,Cno,Grade,Note),当Grade>=60时Note为’通过’,否则为’不通过’。创建一触发器,当修改某学生某门课的成绩Grade时,相应的备注列Note也随之修改。

CREATE TRIGGER tr1_sc1  ON sc1
   AFTER  UPDATE    
AS
   DECLARE @Sn CHAR(8) , @Cn CHAR(4), @G int, @Gnote CHAR(8);
   SELECT    @Sn=Sno, @Cn=Cno, @G=Grade, @Gnote=note      
       FROM INSERTED;
   IF @G>=60  
       UPDATE SC1 SET Note=‘通过’ where Sno= @Sn and  Cno= @Cn
   ELSE
       UPDATE SC1 SET Note=‘不通过’ where Sno= @Sn and  Cno=@Cn

设修改的是课程Cno=‘c001’ 、学生 Sno=‘20160001的成绩为89,则触发该触发器的语句 :

UPDATE SC1 SET Grade=89 WHERE Cno=‘c001’ and Sno=‘20160001’; 

创建INSTEAD OF触发器

定义一触发器XSDA_UPDATE,一旦对XSDA表有任何更新操作,触发器显示“禁止更新!”,并取消所做修改。

CREATE TRIGGER XSDA_UPDATE   ON xsda
  INSTEAD OF UPDATE
AS
  PRINT ‘禁止更新!’;

创建复合触发器

复合触发器:完成多种功能(INSERT、DELETE、UPDATE)的触发器。
创建一触发器tr5_sc ,不允许修改或删除SC表中2011级学生的成绩信息。
(如果是after触发器,则要撤销( ROLLBACK TRANSACTION )对数据库所做的更新操作!)
复合触发器:

CREATE  TRIGGER  tr5_sc   ON sc
AFTER  DELETE, UPDATE 
AS   
DECLARE  @Snum  CHAR(8)
SELECT  @Snum=Sno  FROM  DELETED;
IF  @Snum  LIKE ‘2011_ _ _ _'
 BEGIN 
    ROLLBACK  TRANSACTION
    PRINT  ‘不允许修改或删除2011级学生成绩信息!'
 END

假设要把学生‘20110001’的课程‘c001’ 成绩改为89,则触发该触发器的语句 :

UPDATE SC   SET Grade=89 WHERE Cno=‘c001’ and Sno=‘20110001’; 

或者进行删除操作

DELETE FROM  SCWHERE Cno=‘c001’ and Sno=‘20110001’; 

instead of触发器:

CREATE  TRIGGER  tr5_sc   ON sc
instead of   DELETE, UPDATE 
AS   
DECLARE  @Snum  CHAR(8)
SELECT  @Snum=Sno  FROM  DELETED;
IF  @Snum  LIKE ‘2011_ _ _ _'
 BEGIN 
    PRINT  ‘不允许修改或删除2011级学生成绩信息!'
 END

注:
同一个数据库中触发器名字不能相同,即使不在同一个表(视图)中。

删除触发器

语法格式:

DROP TRIGGER trigger_name[,…]

说明:trigger_name为需要删除的触发器名称,当一次删除多个触发器时,各个触发器名称之间用逗号隔开。
例如:

DROP TRIGGER tr5_sc

修改触发器

ALTER   TRIGGER   <触发器名> 
ON   <表名>
{AFTER|FOR}  {[INSERT][,][UPDATE][,] [DELETE]}
AS
[ SQL 语句 ]

工作量相当于重新创建同名触发器。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容