zoukankan      html  css  js  c++  java
  • 触发器简介

    触发器实际上就是一种特殊类型的存储过程.

    它是在执行某些特定的T-SQL语句时自动执行的一种存储过程。

    在SQL Server 2005中,根据SQL语句的不同,把触发器分为两类:
    一类是DML触发器,
    一类是DLL触发器。

    在SQL Server 2005里,可以用两种方法来保证数据的有效性和完整性:约束和触发器。

    约束是直接设置于数据表内,只能现实一些比较简 单的功能操作,如:实现字段有效性和唯一性的检查、自动填入默认值、确保字段数据不重复(即主键)、确保数据表对应的完整性(即外键)等功能。

    触发器是针对数据表(库)的特殊的存储过程,当这个表发生了 Insert、Update或Delete操作时,会自动激活执行的,可以处理各种复杂的操作。

    在SQL Server 2005中,触发器有了更进一步的功能,在数据表(库)发生Create、Alter和Drop操作时,也会自动激活执行。

    2 触发器常用的一些功能
    1、完成比约束更复杂的数据约束:触发器可以实现比约束更为复杂的数据约束
    2、检查所做的SQL是否允许:触发器可以检查SQL所做的操作是否被允许。例如:在产品库存表里,如果要删除一条产品记录,在删除记录时,触发器可以检查该产品库存数量是否为零,如果不为零则取消该删除操作。
    3、修改其它数据表里的数据:当一个SQL语句对数据表进行操作的时候,触发器可以根据该SQL语句的操作情况来对另一个数据表进行操作。例如:一个订单取消的时候,那么触发器可以自动修改产品库存表,在订购量的字段上减去被取消订单的订购数量。
    4、调用更多的存储过程:约束的本身是不能调用存储过程的,但是触发器本身就是一种存储过程,而存储过程是可以嵌套使用的,所以触发器也可以调用一个或多过存储过程。
    5、发送SQL Mail:在SQL语句执行完之后,触发器可以判断更改过的记录是否达到一定条件,如果达到这个条件的话,触发器可以自动调用SQL Mail来发送邮件。例如:当一个订单交费之后,可以物流人员发送Email,通知他尽快发货。
    6、返回自定义的错误信息:约束是不能返回信息的,而触发器可以。例如插入一条重复记录时,可以返回一个具体的友好的错误信息给前台应用程序。
    7、更改原本要操作的SQL语句:触发器可以修改原本要操作的SQL语句,例如原本的SQL语句是要删除数据表里的记录,但该数据表里的记录是最要记录,不允许删除的,那么触发器可以不执行该语句。
    8、防止数据表构结更改或数据表被删除:为了保护已经建好的数据表,触发器可以在接收到Drop和Alter开头的SQL语句里,不进行对数据表的操作。

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

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

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

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

    4 DML触发器的工作原理
    在SQL Server 2005里,为每个DML触发器都定义了两个特殊的表,一个是插入表,一个是删除表。
    这两个表是建在数据库服务器的内存中的,是由系统管理的逻辑表,而不是真正存储在数据库中的物理表。
    对于这两个表,用户只有读取的权限,没有修改的权限。

    这两个表的结构与触发器所在数据表的结构是完全一致的,当触发器的工作完成之后,这两个表也将会从内存中删除。

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

    删除表里存放的是更新后的记录:对于更新记录操作来说,删除表里存放的是更新前的记录(更新完后即被删除);对于删除记录操作来说,删除表里存入的是被删除的旧记录。

    5 After触发器的工作原理
    After触发器是在记录更变完之后才被激活执行的。

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

    如果触发器表存在约束,则在 INSTEAD OF 触发器执行之后和 AFTER 触发器执行之前检查这些约束。

    如果违反了约束,则将回滚 INSTEAD OF 触发器操作,并且不激活 AFTER 触发器。

    在产品库存表里,如果要删除一条产品记录,在删除记录时,触发器可以检查该产品库存数量是否为零,如果不为零则取消删除操作。看一下数据库是怎么操作的:
    (1)接收SQL语句,将要从产品库存表里删除的产品记录取出来,放在删除表里。
    (2)从产品库存表里删除该产品记录。
    (3)从删除表里读出该产品的库存数量字段,判断是不是为零,如果为零的话,完成操作,从内存里清除删除表;如果不为零的话,用Rollback Transaction语句来回滚操作。

    6 Instead Of触发器的工作原理
    Instead Of触发器与After触发器不同。

    After触发器是在Insert、Update和Delete操作完成后才激活的

    而Instead Of触发器,是在这些操作进行之前就激活了,并且不再去执行原来的SQL操作,而去运行触发器本身的SQL语句。

    7 如何在触发器取得字段修改前和修改后的数据
    SQL Server 2005在为每个触发器都定义了两个虚拟表,插入表(inserted),删除表(deleted)

    以上面删除库存产品记录为例,在删除时触发器要判断库存数量是否为零,那么判断就应该这么写:

    If (Select 库存数量 From Deleted)>0
    Begin
    Print ‘库存数量大于零时不能删除此记录’
    Rollback Transaction
    End

    8 设计简单的触发器
    1、创建触发器
    Create trigger trigger_name
    On table/view
    {for /after/instead of} {insert/update/delete}
    As
    Sql_statement
    如果仅指定 FOR 关键字,则 AFTER 为默认值。
    下面用实例设计一个简单的After Insert触发器,这个触发器的作用是:在student表中插入一条记录的时候,发出“新同学,欢迎你”的友好提示。

    create trigger welcom_stu
    on student
    after insert
    as
    print '欢迎你,新同学!'
    Go

    创建触发器:删除一条学生记录显示“再见,我的同学!”

    create trigger byby_stu on student
    after delete
    as
    print '再见,我的同学!'
    go

    为course建立触发器,禁止删除课程号为‘0’的课程,提示信息为:“必修课,勿删!”。
    Create trigger del_course
    On course
    after delete
    As
    If (select cno from deleted)='0'
    begin
    print '必修课,勿删!'
    rollback transaction
    end

    为student创建一个触发器,当插入一学生记录时,在sc表中生成该学生的选课记录,设置其课程号为’0’。
    create trigger ins_s
    on student
    for insert
    as
    declare @sno char(10)
    select @sno=sno from inserted
    insert into sc(sno,cno) values(@sno,'0')

  • 相关阅读:
    java.sql.SQLException: Access denied for user 'root'@'10.1.0.2' (using password: YES)
    在eclipse中安装使用lombok插件
    Socket编程实践(5) --TCP粘包问题与解决
    Socket编程实践(8) --Select-I/O复用
    Socket编程实践(6) --TCP服务端注意事项
    Socket编程实践(4) --多进程并发server
    Socket编程实践(3) --Socket API
    Socket编程实践(2) --Socket编程导引
    Socket编程实践(1) --TCP/IP简述
    Socket编程实践(11) --epoll原理与封装
  • 原文地址:https://www.cnblogs.com/xianmin/p/14015703.html
Copyright © 2011-2022 走看看