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(此處為自動生成的主鍵),可能有所不同.