(转)菜鸟学数据库(二)——触发器

摘要:
按钮的单击事件通过用鼠标单击按钮来触发,而触发事件通过添加、删除和修改表来触发。添加、删除或修改数据库或表时将激活触发器。DDL触发器通常用于在数据库中执行管理任务。这两个表的结构与触发器所在的数据表的结构完全相同。当触发器的工作完成时,这两个表也将从内存中删除。两个触发器都不能构建在临时表上。6.触发器名称在数据库中必须是唯一的。

本人水平有限,写此博客只为给那些像我一样的菜鸟一点小小的帮助,还请各位大牛不要见笑。

数据库的重要性就不用我多说了吧,我们做的大多数项目都要跟数据库打交道。因此,熟练掌握数据库的各种操作,就成了一个程序员必备的技能。今天我们就来简单说一下触发器。

这篇文章只是对触发器的理论总结,要想彻底了解触发器,参考SqlServer基础之(触发器)(清晰易懂)

触发器简介:

触发器(trigger)是种特殊的存储过程,它的执行不是由程序调用,也不需要手动操作,它是由事件来触发,事件大家应该非常熟悉吧,比如按钮的Click事件、网页的Load事件等。按钮的Click事件是通过鼠标单击按钮触发的,而触发器的事件,是由对表进行增删改操作所触发的。当对一个数据库进行增删改( Insert,Delete,Update)的时就会激活触发器。

从SQL2005开始,根据SQL语句的不同将触发器分成了两类,一类是DML触发器,一类是DLL触发器。其中DML触发器又分为两类:After触发器和Instead Of触发器。


触发器的分类:

DML触发器:DML(Data Manipulation Language)触发器是当数据库服务器中发生数据操作语言事件时执行的存储过程。DML触发器又分为两类:After触发器和Instead Of触发器

DDL触发器:DDL触发器是在响应数据定义语言(Data Definition Language)事件时执行的存储过程。DDL触发器一般用于执行数据库中管理任务。如审核和规范数据库操作、防止数据库表结构被修改等。


DML触发器:

今天我们我们主要介绍DML触发器,DML触发器分为After触发器和Instead Of触发器。

After触发器:这类触发器是在记录已经改变完之后(after),才会被激活执行,它主要是用于记录变更后的处理或检查,一旦发现错误,也可以用Rollback Transaction语句来回滚本次的操作。

Instead Of触发器:这类触发器一般是用来取代原本的操作,在记录变更之前发生的,它并不去执行原来SQL语句里的操作(Insert、Update、Delete),而去执行触发器本身所定义的操作。

在SQL Server里,每个DML触发器都分配有两个特殊的表,一个是Inserted表,一个是Deleted表。它们两个存在于数据库服务器的内存中,是由系统管理的逻辑表,是两个临时表,而不是真正存储在数据库中的物理表。用户对这两个表只有读取的权限,没有修改的权限。

这两个表的结构(主外键、字段、数据类型等)与触发器所在数据表的结构是完全一致的,当触发器的工作完成之后,这两个表也将会从内存中删除。


Inserted和Deleted两个表的作用:

Inserted:对于插入记录操作来说,插入表里存放的是要插入的数据;对于更新记录操作来说,插入表里存放的是要更新的记录。

Deleted:对于更新记录操作来说,删除表里存放的是被更新记录;对于删除记录操作来说,删除表里存入的是被删除的旧记录。


看上面两句话可能不太明白,那么看看下面这张表是不是就明白了?

 

(转)菜鸟学数据库(二)——触发器第1张




工作原理:

 


After触发器的工作原理:


After触发器是在SQL语句执行之后才被激活的。以删除记录为例:当SQL Server接收到一条删除操作的SQL语句时,SQL Server先将要删除的记录存放在Deleted表里,然后把数据表里的记录删除,再激活After触发器,执行After触发器里的SQL语句。执行完毕之后, 删除内存中的Deleted表,操作结束。

还是举上面的例子:在产品库存表里,如果要删除一条产品记录,在删除的时候,触发器可以检查该产品库存数量是否为零,如果不为零则取消删除操作。数据库的操作如下:

1,接收SQL语句,将要从产品库存表里删除的产品记录取出来,放在删除表里。

2,从产品库存表里删除该产品记录。

3,从删除表里读出该产品的库存数量字段,判断是不是为零,如果为零的话,完成操作,从内存里清除删除表;如果不为零的话,用Rollback Transaction语句来回滚操作(即将库存表还原成删除之前的状态)。


Instead Of 触发器的工作原理:


Instead Of触发器与After触发器不同。After触发器是在Insert、Update和Delete操作完成后才激活的,而Instead Of触发器,是在这些操作进行之前就激活了,并且不再去执行原来的SQL操作,而是用触发器本身的SQL语句代替原来的语句去执行。

还拿上面那个例子来说,删除一条产品记录的时候,用Instead Of将删除操作替换成查询该产品的库存。数据库的操作如下:

1,接收SQL语句,但不执行,而是跳转到Instead Of后面的SQL语句

2,根据传入的产品ID,将该产品的库存取出,完成操作。


说了那么多理论上的东西,下面让我们看看触发器的代码到底怎么写:

下面的一段代码是触发器的一个框架。

 

  1. CREATE TRIGGER  Trigger_Name --触发器名,在一个数据库中触发器名是唯一的。  
  2.   
  3.   
  4.   
  5.   
  6.    ON  Table_Name | View_Name --触发器所在的表或者视图。  
  7.   
  8.   
  9.   
  10.   
  11.    AFTER(FOR)|Instead Of  INSERT,DELETE,UPDATE --定义成AFTER或Instead Of类型的触发器。  
  12.      
  13.    --AFTER跟FOR相同,不可在视图上定义AFTER触发器  
  14.      
  15.    -- 后面是触发器被触发的条件,最少有一个,可以邮多个。如果有多个用逗号分开,顺序无要求。  
  16.   
  17.   
  18.   
  19.   
  20. AS --触发器要执行的操作  
  21.   
  22.   
  23. BEGIN  
  24.       
  25.    --BEGIN跟END组成一个代码块,可以写也可以不写,如果触发器中执行的SQL语句比较复杂,用BEGIN和END会让代码更加整齐,更容易理解。   
  26.       
  27.   
  28.   
  29. END  
  30. GO --GO就代表结操作完毕  


 


注意事项:

 


1,After触发器只能用于数据表不能用于视图;Instead Of触发器两者皆可,设置为With Check Option的视图也不允许建立Instead Of触发器。两种触发器都不可以建立在临时表上。

2,一个数据表可以有多个触发器,但是一个触发器只能对应一个表。

3,在同一个数据表中,对每个操作(如Insert、Update、Delete)而言可以建立许多个After触发器,而Instead Of触发器针对每个操作只有建立一个。

4,如果针对某个操作即设置了After触发器又设置了Instead Of触发器,那么Instead of触发器一定会激活,而After触发器就不一定会激活。

5,不同的SQL语句,可以触发同一个触发器,如Insert和Update语句都可以激活同一个触发器。

6,触发器名在所在的数据库里必须是唯一的。由于触发器是建立中数据表或视图中的,所以有很多人都以为只要是在不同的数据表中,触发器的名称就可以相同,其实触发器的全名(Server.Database.Owner.TriggerName)是必须 唯一的,这与触发器在哪个数据表或视图无关。

7,关键字AFTER可以用For来代取,它们的意思都是一样的,代表只有在数据表的操作都已正确完成后才会激活的触发器。


免责声明:文章转载自《(转)菜鸟学数据库(二)——触发器》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇数据建模与框架设计的暂时总结java容器类下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Java下拼接执行动态SQL语句(转)

     在实际业务中经常需要拼接动态SQL来完成复杂数据计算,网上各类技术论坛都有讨论,比如下面这些问题:         http://bbs.csdn.net/topics/390876591         http://bbs.csdn.net/topics/390981627         https://www.linkedin.com/g...

C#连接SQLServer数据库

usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; usingSystem.Threading.Tasks; usingSystem.Data; usingSystem.Data.Sql; usingSystem.Data.SqlClient;...

Mybatis中的DataSource配置

dataSource 的类型可以配置成其内置类型之一,如 UNPOOLED,POOLED,JNDI。 1、如果将类型设置成 UNPOOLED,MyBatis 会为每一个数据库操作创建一个新的连接,并关闭它。该方式 适用于只有小规模数量并发用户的简单应用程序上。 2、 如果将属性设置成 POOLED,MyBatis 会创建一个数据库连接池,连接池中的一个连接...

如何在oracle中导入dmp数据库文件

如何在oracle中导入dmp数据库文件 --如何在oracle中导入dmp数据库文件                          Oracle数据导入导出imp/exp就相当于oracle数据还原与备份。exp命令可以把数据从远程数据库服务器导出到本地的dmp文件,imp命令可以把dmp文件从本地导入到远处的数据库服务器中。 利用这个功能可以构...

解决delphi使用sqlite时中文最后一个字是乱码的问题

           给部门同事写了个自动生成测试用例执行情况图表的工具,使用的sqlite3,遇到中文分别使用UTF8Encode和UTF8Decode进行处理,可还是出现了某些字段从数据库中读出时,最后一个汉字是乱码的情况。   自己看了一下SQLiteTable3.pas的代码,发现从数据库中读出utf8字符时用setstring进行了强制转换,造成...

Flask web开发之路七

今天写SQLAlchemy数据库  首先介绍ORM的概念: ORM,Object类,Relationship:关系,Mapping:映射,也就是模型关系映射 flask-sqlalchemy是一套ORM框架 ORM的好处:可以让我们操作数据库跟操作对象一样,非常方便,因为一个表就抽象成一个类,一条数据就抽象成该类的一个对象;把高层的面向对象操作转换成低层的...