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(此处为自动生成的主键),可能有所不同.