zoukankan      html  css  js  c++  java
  • SQL Server基础:触发器实现增删改,数据验证及同步到新表

    SQL Server中触发器常用于对一个表的更新、插入及删除后操作,和Oracle触发器类似,都有after触发器类型,但SQL Server没有before类型。

    原理不多讲,上一张网上的原理图,差不多就很清楚了.

    下面通过一个例子实现在SQL Server 中通过触发器删除、插入和修改数据并同步到新表

     1 ---创建一张表
     2 create table test_01
     3 (
     4    id int identity(1,1)  primary key,
     5    userID  int not null,
     6    name varchar(50)  not null,
     7    sex nvarchar(2)  not null,
     8    age int null
     9 )
    10 
    11 ---复制表结构到新表
    12 select * into test_02 from test_01

    然后,我们创建一个触发器

     1 --已存在,先删除
     2 if(exists (select * from  sysobjects where xtype='tr' and name='tri_test01'))
     3 begin
     4   drop trigger tri_test01
     5   print '已删除'
     6   end
     7   go
     8 
     9   ---创建触发器
    10 create trigger tri_test01 on test_01
    11 after insert,update,delete
    12 as
    13 begin
    14     --禁止返回受影响行数
    15     --SET NOCOUNT ON;
    16 
    17     declare  @isDel  bit  =  0
    18     declare  @isIns  bit  =  0
    19     declare  @changeType varchar(20)
    20 
    21     -- 如果在DELETED内部临时触发表找到记录,说明旧数据被删除 
    22     if  exists( select  top  1  1  from deleted)
    23        set  @isDel  =  1
    24     
    25     -- 如果在inserted内部临时触发表找到记录,说明有新数据插入     
    26     if  exists( select  top  1  1  from inserted)
    27          set  @isIns  =  1  
    28 
    29     -- 如果两个表都有记录,说明触发器是执行更新触发
    30     if  @isIns  =  1  and  @isDel  =  1 
    31         set @changeType='UPDATE'
    32 
    33     -- 如果变量@i值被变更为1,而变量@d没有变更,说明触发器是执行插入触发    
    34     if  @isIns  =  1  and  @isDel  =  0
    35         set @changeType='INSERT'
    36  
    37     -- 下面判断成立,说明说明触发器是执行删除触发    
    38     if  @isIns  =  0  and  @isDel  =  1
    39         set @changeType='DELETE'
    40 
    41     declare @userID int,@age int,@sex nvarchar,@maxid int
    42     if(@changeType='INSERT')
    43            begin
    44          print(' 插入 ')
    45          select @userID=userID,@age=age,@sex=sex from inserted
    46 
    47          ---如果触发器类型是before,此处可以判断ID是否存在重复
    48          ---可惜SQL Server不支持before触发器
    49         --if exists ( select 1 from test_01  where userID = @userID )
    50         --  begin
    51         --      print '用户ID不能重复 '
    52         --      rollback transaction   --回滚
    53         --  end
    54         
    55         if(@age>=200 AND @age is not null)
    56           begin
    57               print '人不可能长命百岁 '
    58               rollback transaction   --回滚
    59           end
    60         else if(@sex!='' AND @sex!='')
    61           begin
    62               print '人不可能不男不女 '
    63               rollback transaction   --回滚
    64           end
    65          else
    66            begin    
    67              insert into test_02(userID,name,sex,age)
    68              select userID,name,sex,age from inserted  --插入到新表
    69            end
    70         end
    71         ----
    72       else if(@changeType='UPDATE')
    73       begin
    74         print ('更新')
    75         if UPDATE(age)  ---更新age字段
    76         begin
    77               update test_02 set age  = inserted.age
    78               from test_02 ,deleted,inserted
    79               where test_02.age = deleted.age
    80         end
    81       end
    82       ----
    83       else if(@changeType='DELETE')
    84       begin
    85          select  @maxid = userID  from  deleted; 
    86         if exists ( select count(1) from  test_02  where userID = @maxid )
    87         begin 
    88            delete  from test_02  where  userID = @maxid;    
    89         end
    90       end
    91 end

    以上触发器中,如果要判断一个用户ID是否已经存在,假设我没有为这个ID加入主键,想通过触发器判断,那么alter触发器不能实现,可以在评论说说你的解决方法.

    如果触发器为更新,那么需要先删除新表已有数据,再新插入数据。例子中给的age字段只是示例,实际操作中建议以主键字段来判断。

    删除的情况下,只用判断主键是否存在,已存在同步删除就OK了。

    看看实际效果。。。

    由于插入的时候存在触发验证的情况,若验证不通过将回滚操作,但已生成的主键值不会跟着回滚,所以两张表的主键ID(此处为自动生成的主键),可能有所不同.

  • 相关阅读:
    Scilab5.5.2 在Centos5.11下binary安装(注:不是源码编译安装)
    《DSP using MATLAB》Problem 9.5
    Java 出现警告 不能读取AppletViewer的属性文件
    《DSP using MATLAB》Problem 9.4
    《DSP using MATLAB》Problem 9.2
    《DSP using MATLAB》Problem 8.46
    《DSP using MATLAB》Problem 8.45
    风力摆?这是不是太简单了点
    树莓派:基于物联网做的指纹打卡器
    Python之面向对象(一)
  • 原文地址:https://www.cnblogs.com/healer007/p/14554345.html
Copyright © 2011-2022 走看看