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)

  • 相关阅读:
    动态传参
    函数的介绍
    文件的操作
    send email with formatted table
    minimize and close window with customed winform
    python algorithm
    something important about docker
    book list
    which language is suitable for what to do
    Find Duplicate Items in list fast
  • 原文地址:https://www.cnblogs.com/key1309/p/3400701.html
Copyright © 2011-2022 走看看