zoukankan      html  css  js  c++  java
  • 转载作为笔记:触发器

     

    触发器总结

    触发器的总结:
    触发器是一种特殊的存储过程,其特殊性在于它并不需由用户来直接调用,当对表进行插入、修改、删除操作时自动执行。所以,触发器可以用来实施复杂的完整性约束。
     


    触发器的优点:
    1.可实现数据库中多张表的级联更新。
    2.实现比CHECK约束更为复杂的约束。使用CHECK约束,可以限制不满足检查条件的记录输入表中。CHECK约束的检查条件表达式不允许引用其它表中的字段,而触发器可引用其它表中的字段。

    触发器的触发方式:
      AFTER或FOR 关键字指定 后触发:当引起触发器执行的更新语句执行完成,并通过各种约束检查后,才执行后触发,这种触发方式称做后触发
      INSTEAD OF 关键字指定 替代触发:引起触发器执行的更新语句停止执行,仅执行触发器语句,这种触发方式称做替代触发

    inserted临时表和deleted临时表:
     
    每个触发器被激活时,系统都会为它自动创建两个临时表: inserted表和deleted表。这两个表的结构总是与激活触发器的表的结构相同,触发器执行完成后,与该触发器相关的这两个临时表也会被自动删除。
    在执行DELETE语句删除表中的数据时,系统将数据从表中删除的同时,自动把删除的数据插入到deleted这一系统临时表中;当执行INSERT语句向表中插入数据时,系统将数据插入表的同时,也把相应的数据插入到inserted这一系统临时表中;在执行UPDATE语句修改表数据时,系统先从表中删除表中原有的行,然后再插入新行。其中被删除的行存放在deleted表中,同时插入的新行存放在inserted表中。

    注意:
    1.CREATE TRIGGER语句必须是一个批处理中的第一条语句。
    2.触发器只能在当前的数据库创建,但触发器可能引用其它数据对象。
    3.如果指定触发器所有者名限定触发器,要以相同方式限定表名。
    4.在同一CREATE TRIGGER语句中,可以为多种操作定义相同的触发器操作。
    5.如果一个表的外键在DELETE、UPDATE操作上定义了级联,则不能在该表上定义INSTEAD OF DELETE、INSTEAD OF UPDATE触发器。
    6.所有建立和修改数据库及其对象的语句、所有DROP语句都不允许在触发器使用。
    7.触发器不返回任何结果,为了阻止从触发器返回结果,不要在触发器定义中包含SELECT语句或变量赋值。如果必须在触发器中进行变量赋值,则应该在触发器的开头使用SET NOCOUNT ON语句以避免返回任何结果集。

    完整形式:
    1. 语法格式
     
    CREATE TRIGGER trigger_name ON { table | view }  /*指定触发器名及操作对象*/
     
             [ WITH ENCRYPTION ]                                 /*说明是否采用加密方式*/
     
             { FOR | AFTER | INSTEAD OF } { [DELETE] [,] [INSERT] [,] [UPDATE] }
     
             /*定义触发器的类型*/      

             [ NOT FOR REPLICATION ]                              /*说明该触发器不用于复制*/
     
             AS
     
             [ { IF UPDATE ( column ) [ { AND | OR } UPDATE ( column ) ]
     
                       [ ...n ]             

                   | IF ( COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask )
     
                       { comparison_operator } column_bitmask [ ...n ]
     
              } ]                                       /*两个IF子句用于说明触发器执行的条件*/
     
              sql_statements                     /* T- SQL语句序列*/


    ============
    后触发:
    ==========


    例15.1 对于school数据库,如果在student表中添加或更改数据,则向客户端显示一条信息。
     

    USE XSBOOK
    IF EXISTS (SELECT name FROM sysobjects
           WHERE name = 'reminder' AND type = 'TR')
           DROP TRIGGER reminder
    GO
    CREATE TRIGGER reminder ON student
           FOR INSERT, UPDATE
           AS RAISERROR (13001, 16, 10)          /*使用带有提示消息的触发器*/
    GO


    -------------------


    例15.2  在数据库school中创建一触发器,当向score表中插入一记录时,检查该记录的sno在student表是否存在,检查cno号在course表中是否存在,若有一项为否,则不允许插入,并返回“数据不一致”错误信息。
     
    CREATE TRIGGER TR_score ON score
    FOR INSERT
    AS
    IF NOT EXISTS(SELECT * FROM student WHERE sno =(SELECT sno FROM inserted)) OR
       NOT EXISTS(SELECT * FROM course WHERE cno =(SELECT cno FROM inserted))
    BEGIN
          RAISERROR('数据不一致',16,1)
          ROLLBACK TRANSACTION
     END


    ---------------

    例15.3         在school数据库的score表上创建一触发器,若对sno列和cno列修改,则给出提示信息,并取消修改操作,用两种方法实现。
     
    CREATE TRIGGER TR1_score ON score
    FOR UPDATE
    AS
    IF UPDATE(sno) OR UPDATE(cno)
      BEGIN
        RAISERROR('不允许修改',16,1)
        ROLLBACK TRANSACTION
      END

    ====================
    INSTEAD OF 触发器
    ====================

    CREATE VIEW VIEW2         /*替换触发器可用于试图*/
    AS
    SELECT sno,sname,ssex,sbirthday,class
    FROM student

     
    CREATE TRIGGER INSTEADOFTR_VIEW2 ON VIEW2
    INSTEAD OF INSERT
    AS
    BEGIN
    INSERT INTO student(sno,sname,class)
    SELECT sno,sname,class FROM inserted
    END


    --------------------


    向score表插入一条学生选课记录,如果该记录学生成绩低于60分,则把他成绩改为60分。
     
    CREATE TRIGGER S1 ON score           /*用For形式实现*/
    FOR INSERT
    AS
    BEGIN
    DECLARE @num1 char(5),@num2 char(10)
      IF (SELECT degree FROM inserted)<60
       BEGIN
        SET @num1=(SELECT sno FROM inserted)
        SET @num2=(SELECT cno FROM inserted)
        UPDATE score SET degree=60 WHERE sno=@num1 AND cno=@num2
       END
    END
     
     
     
    CREATE TRIGGER S1 ON score             /*用替换触发器 实现*/
    INSTEAD OF INSERT
    AS
    BEGIN
    DECLARE @num1 char(10),@num2 char(10)
      IF (SELECT degree FROM inserted)<60
       BEGIN
        SET @num1=(SELECT sno FROM inserted)
        SET @num2=(SELECT cno FROM inserted)
        INSERT INTO score VALUES(@num1,@num2,60)
       END
    END
     

    INSERT INTO SC VALUES('95001','5',50)
    INSERT INTO SC VALUES('95001','6',99)

  • 相关阅读:
    新代(Syntec)机床的IP设置
    使用任务计划程序实现用户未登录情况下的程序开机自启动
    sql server 数据库访问端口配置
    Http请求
    EF
    SQL Server常用处理
    利用ZXing生成条码二维码例子
    SQL JOIN常见情况
    C#ORM框架收集
    sql server连接oracle并实现增删改查
  • 原文地址:https://www.cnblogs.com/key1309/p/3400701.html
Copyright © 2011-2022 走看看