zoukankan      html  css  js  c++  java
  • 前触发器和后触发器简介(downmoon)

                    前触发器和后触发器简介(downmoon)

         触发器是一种特殊的存储过程。当Insert Update 或者Delete 语句修改表中一个或者多个行时执行触发器。因为SQL Server 对特定表上的每一个指定操作调用一个触发器,所以可以使用触发器扩展SQL Sever 的内置完整性和数据操纵功能.
         注意:不像Delete 语句,Trancate Table 语句不激活触发器,Write Text 语句也不激活触发器。
         在SQL Sever 2000 中支持两种类型的触发器,前触发器(Instead Of Trigger)和后触发器(After Trigger)。前触发器就是在语句执行之前激活触发器,而后触发器就是在语句执行之后激活触发器。可以通过FOR 子句来选择使用何种触发器。
         当为每一种操作创建一个触发器时,可以为所有三种操作创建一个触发器,并且使用相应的编程技术处理每一种操作。下面的示例在For 子句中列出了三种语句类型并,且使用条件语句将相应的跟踪值插入到CustUpdLog 表中。
    Create Trigger TrackCustomerUpdates
       On AppDta.dbo.Customer
          For Insert,Update,Delete
       As
          Declare @InsertedCount Int
          Declare @DeletedCount Int
          Set @InsertedCount=(Select Count(*)From inserted)
          Set @DeletedCount=(Select Count(*)From deleted)
          If ( @InsertedCount>0)
             Begin
                Insert Into AppDta.dbo.CustUpdLog
                ( CustID,
                   Action,
                   UpdUser,
                   UpdDateTime)
                Select CustId,
                Case
                When( @DeletedCount>0)Then
                'Update'
            Else 'Insert'
          End,
    Current_User,
    Current_TimeStamp
    From inserted
    End
    Else If(@DeletedCount>0)Begin
    Insert Into AppDta.dbo.CustUpdLog
    ( CustId,
    Action,
    UpdUser,
    UpdDateTime)
    select CustId,
    'Delete',
    Current_User,
    Current_TimeStamp
    From deleted
    End
        正如本例所示,无论何时Insert 或者Update 语句影响一个或者多行时,inserted 临时表都有记录行。无论何时Delete 或者Update 语句影响一个或者多行时,deleted 临时表都有记录行。对于一个Update 语句,deleted 临时表有旧行,inserted 临时表有新行。这个示例还反映了触发器的另一个重要方面:对于某个表的Update 或者Delete 操作,即使该语句没有影响到行,也激活触发器 (也就是说没有满足Where 子句的行)。 触发器的存储过程应该预测这种可能性。


        不仅可以为一个表创建多个触发器,而且还可以为一个表的同一个SQL 语句(例如Update 语句)创建多个后触发器,不能为同一个SQL 语句创建多个前触发器。每一个新的Create Trigger 语句增加触发器到那些指定表和语句已有的触发器中。对于所创建的多个触发器,可以用系统存储过程sp_settriggerorder 来指定第一个被激活的触发器和最后一个被激活的触发器,而对于其他的触发器,则不能指定其激活顺序,只能由系统决定。这种触发器的特征不会引起任何特殊的问题。因为总是可以实现各种动作作为正常的存储过程,并且按照要求的顺序从一个触发器中调用它们。

        尽管触发器是一种存储过程,但是不能使用Execute 语句调用它,如果有希望共享触发器和正常的存储过程的编码,那么只需把共享代码放在存储过程中,从触发器中调用它。如果一个触发器修改一个表,那么这些修改可能会激活另一个触发器,或者本身。在默认情况下,SQL Sever 允许这种嵌套的触发器调用深度为32层。虽然我们建议允许嵌套的和叠代的触发器,但是可以使用系统存储过程禁止这么做。下面的语句在指定的数据库上防止叠代触发器:
    sp_dboption AppDta,`recursive triggers',`false'
        为了在所有数据库中防止嵌套触发器调用(包括叠代调用),可以使用下面的语句:
    sp_configure `nested triggers',0

        前面以后触发器为例介绍了触发器的基本内容,下面再介绍一下前触发器的不同之处。要创建一个前触发器必须用Instead Of 显式声明,如下面的例子:
    create Trigger TrackCustomerUpdates
    On AppDta.dbo.Customer
    Instead Of Update
    As
    Insert Into AppDta.dbo.CustUpdLog
    (CustId,
    Action,
    UpdUser,
    UpdDateTime)
    Select CustId,
    ‘Update’,
    Current_User,
    Current_TimeStamp
    From inserted
        与后触发器不同的是:前触发器既可以在表又可以在视图上创建,但一条语句只能创建一个前触发器,因此,前触发器不存在激活顺序问题


    触发器应用举例:从当前数据库服务器的Shop表Insert操作同步到另一台服务器的Shop。

    CREATE TRIGGER Trigger_SynShopForInsert1
    ON dbo.Shop
    FOR INSERT
    AS
      insert into OtherServer.dbo.shop
    (
    lngShopID,strShopCode,strName,strShopName,strDescription,lngIndex
    )
    select  lngShopID,strShopCode,strName,strShopName,strDescription,lngIndex
    from shop where lngShopID in (select lngshopid from inserted)

    或者:

    CREATE TRIGGER Trigger_SynShopForInsert2
    ON dbo.Shop
    FOR INSERT
    AS
      insert into OtherServer.dbo.shop
    (
    lngShopID,strShopCode,strName,strShopName,strDescription,lngIndex
    )
    select  lngShopID,strShopCode,strName,strShopName,strDescription,lngIndex
    from  inserted
  • 相关阅读:
    linux 解压tgz 文件指令
    shell 脚本没有执行权限 报错 bash: ./myshell.sh: Permission denied
    linux 启动solr 报错 Your Max Processes Limit is currently 31202. It should be set to 65000 to avoid operational disruption.
    远程查询批量导入数据
    修改 MZTreeView 赋权节点父节点选中子节点自动选中的问题
    关于乱码的问题解决记录
    我的网站优化之路
    对设计及重构的一点反思
    我的五年岁月
    奔三的路上
  • 原文地址:https://www.cnblogs.com/fengye/p/639386.html
Copyright © 2011-2022 走看看