国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 數(shù)據(jù)庫(kù) > SQL Server > 正文

深入淺析SQL Server 觸發(fā)器

2024-08-31 01:03:16
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

觸發(fā)器是一種特殊的存儲(chǔ)過(guò)程,觸發(fā)器是通過(guò)事件觸發(fā)可以自動(dòng)調(diào)用執(zhí)行的。在sql2005中,觸發(fā)器可以分為dml觸發(fā)器和ddl觸發(fā)器。下面通過(guò)本篇文章給大家深入淺析sqlserver觸發(fā)器,需要的朋友可以參考下

觸發(fā)器是一種特殊類型的存儲(chǔ)過(guò)程,它不同于之前的我們介紹的存儲(chǔ)過(guò)程。觸發(fā)器主要是通過(guò)事件進(jìn)行觸發(fā)被自動(dòng)調(diào)用執(zhí)行的。而存儲(chǔ)過(guò)程可以通過(guò)存儲(chǔ)過(guò)程的名稱被調(diào)用。

Ø 什么是觸發(fā)器

觸發(fā)器對(duì)表進(jìn)行插入、更新、刪除的時(shí)候會(huì)自動(dòng)執(zhí)行的特殊存儲(chǔ)過(guò)程。觸發(fā)器一般用在check約束更加復(fù)雜的約束上面。觸發(fā)器和普通的存儲(chǔ)過(guò)程的區(qū)別是:觸發(fā)器是當(dāng)對(duì)某一個(gè)表進(jìn)行操作。諸如:update、insert、delete這些操作的時(shí)候,系統(tǒng)會(huì)自動(dòng)調(diào)用執(zhí)行該表上對(duì)應(yīng)的觸發(fā)器。SQL Server 2005中觸發(fā)器可以分為兩類:DML觸發(fā)器和DDL觸發(fā)器,其中DDL觸發(fā)器它們會(huì)影響多種數(shù)據(jù)定義語(yǔ)言語(yǔ)句而激發(fā),這些語(yǔ)句有create、alter、drop語(yǔ)句。

DML觸發(fā)器分為:

1、 after觸發(fā)器(之后觸發(fā))

a、 insert觸發(fā)器

b、 update觸發(fā)器

c、 delete觸發(fā)器

2、 instead of 觸發(fā)器 (之前觸發(fā))

其中after觸發(fā)器要求只有執(zhí)行某一操作insert、update、delete之后觸發(fā)器才被觸發(fā),且只能定義在表上。而instead of觸發(fā)器表示并不執(zhí)行其定義的操作(insert、update、delete)而僅是執(zhí)行觸發(fā)器本身。既可以在表上定義instead of觸發(fā)器,也可以在視圖上定義。

觸發(fā)器有兩個(gè)特殊的表:插入表(instered表)和刪除表(deleted表)。這兩張是邏輯表也是虛表。有系統(tǒng)在內(nèi)存中創(chuàng)建者兩張表,不會(huì)存儲(chǔ)在數(shù)據(jù)庫(kù)中。而且兩張表的都是只讀的,只能讀取數(shù)據(jù)而不能修改數(shù)據(jù)。這兩張表的結(jié)果總是與被改觸發(fā)器應(yīng)用的表的結(jié)構(gòu)相同。當(dāng)觸發(fā)器完成工作后,這兩張表就會(huì)被刪除。Inserted表的數(shù)據(jù)是插入或是修改后的數(shù)據(jù),而deleted表的數(shù)據(jù)是更新前的或是刪除的數(shù)據(jù)。

Update數(shù)據(jù)的時(shí)候就是先刪除表記錄,然后增加一條記錄。這樣在inserted和deleted表就都有update后的數(shù)據(jù)記錄了。注意的是:觸發(fā)器本身就是一個(gè)事務(wù),所以在觸發(fā)器里面可以對(duì)修改數(shù)據(jù)進(jìn)行一些特殊的檢查。如果不滿足可以利用事務(wù)回滾,撤銷操作。

Ø 創(chuàng)建觸發(fā)器

語(yǔ)法

 

 
  1. create trigger tgr_name 
  2. on table_name 
  3. with encrypion –加密觸發(fā)器 
  4. for update... 
  5. as 
  6. Transact-SQL 
  7. # 創(chuàng)建insert類型觸發(fā)器 
  8. --創(chuàng)建insert插入類型觸發(fā)器 
  9. if (object_id('tgr_classes_insert''tr') is not null
  10. drop trigger tgr_classes_insert 
  11. go 
  12. create trigger tgr_classes_insert 
  13. on classes 
  14. for insert --插入觸發(fā) 
  15. as 
  16. --定義變量 
  17. declare @id int, @name varchar(20), @temp int
  18. --在inserted表中查詢已經(jīng)插入記錄信息 
  19. select @id = id, @name = name from inserted; 
  20. set @name = @name + convert(varchar, @id); 
  21. set @temp = @id / 2;  
  22. insert into student values(@name, 18 + @id, @temp, @id); 
  23. print '添加學(xué)生成功!'
  24. go 
  25. --插入數(shù)據(jù) 
  26. insert into classes values('5班', getDate()); 
  27. --查詢數(shù)據(jù) 
  28. select * from classes; 
  29. select * from student order by id; 
  30. insert觸發(fā)器,會(huì)在inserted表中添加一條剛插入的記錄。 
  31. # 創(chuàng)建delete類型觸發(fā)器 
  32. --delete刪除類型觸發(fā)器 
  33. if (object_id('tgr_classes_delete''TR') is not null
  34. drop trigger tgr_classes_delete 
  35. go 
  36. create trigger tgr_classes_delete 
  37. on classes 
  38. for delete --刪除觸發(fā) 
  39. as 
  40. print '備份數(shù)據(jù)中……';  
  41. if (object_id('classesBackup''U') is not null
  42. --存在classesBackup,直接插入數(shù)據(jù) 
  43. insert into classesBackup select name, createDate from deleted; 
  44. else 
  45. --不存在classesBackup創(chuàng)建再插入 
  46. select * into classesBackup from deleted; 
  47. print '備份數(shù)據(jù)成功!'
  48. go 
  49. -- 
  50. --不顯示影響行數(shù) 
  51. --set nocount on; 
  52. delete classes where name = '5班'
  53. --查詢數(shù)據(jù) 
  54. select * from classes; 
  55. select * from classesBackup; 
  56. delete觸發(fā)器會(huì)在刪除數(shù)據(jù)的時(shí)候,將剛才刪除的數(shù)據(jù)保存在deleted表中。 
  57. # 創(chuàng)建update類型觸發(fā)器 
  58. --update更新類型觸發(fā)器 
  59. if (object_id('tgr_classes_update''TR') is not null
  60. drop trigger tgr_classes_update 
  61. go 
  62. create trigger tgr_classes_update 
  63. on classes 
  64. for update 
  65. as 
  66. declare @oldName varchar(20), @newName varchar(20); 
  67. --更新前的數(shù)據(jù) 
  68. select @oldName = name from deleted; 
  69. if (exists (select * from student where name like '%'+ @oldName + '%')) 
  70. begin 
  71. --更新后的數(shù)據(jù) 
  72. select @newName = name from inserted; 
  73. update student set name = replace(name, @oldName, @newName) where name like '%'+ @oldName + '%'
  74. print '級(jí)聯(lián)修改數(shù)據(jù)成功!'
  75. end 
  76. else 
  77. print '無(wú)需修改student表!'
  78. go 
  79. --查詢數(shù)據(jù) 
  80. select * from student order by id; 
  81. select * from classes; 
  82. update classes set name = '五班' where name = '5班'
  83. update觸發(fā)器會(huì)在更新數(shù)據(jù)后,將更新前的數(shù)據(jù)保存在deleted表中,更新后的數(shù)據(jù)保存在inserted表中。 
  84. # update更新列級(jí)觸發(fā)器 
  85. if (object_id('tgr_classes_update_column''TR') is not null
  86. drop trigger tgr_classes_update_column 
  87. go 
  88. create trigger tgr_classes_update_column 
  89. on classes 
  90. for update 
  91. as 
  92. --列級(jí)觸發(fā)器:是否更新了班級(jí)創(chuàng)建時(shí)間 
  93. if (update(createDate)) 
  94. begin 
  95. raisError('系統(tǒng)提示:班級(jí)創(chuàng)建時(shí)間不能修改!', 16, 11); 
  96. rollback tran; 
  97. end 
  98. go 
  99. --測(cè)試 
  100. select * from student order by id; 
  101. select * from classes; 
  102. update classes set createDate = getDate() where id = 3; 
  103. update classes set name = '四班' where id = 7; 
  104. 更新列級(jí)觸發(fā)器可以用update是否判斷更新列記錄; 
  105. # instead of類型觸發(fā)器 
  106. instead of觸發(fā)器表示并不執(zhí)行其定義的操作(insert、update、delete)而僅是執(zhí)行觸發(fā)器本身的內(nèi)容。 
  107. 創(chuàng)建語(yǔ)法 
  108. create trigger tgr_name 
  109. on table_name 
  110. with encryption 
  111. instead of update... 
  112. as 
  113. T-SQL 
  114. # 創(chuàng)建instead of觸發(fā)器 
  115. if (object_id('tgr_classes_inteadOf''TR') is not null
  116. drop trigger tgr_classes_inteadOf 
  117. go 
  118. create trigger tgr_classes_inteadOf 
  119. on classes 
  120. instead of delete/*, update, insert*/ 
  121. as 
  122. declare @id int, @name varchar(20); 
  123. --查詢被刪除的信息,病賦值 
  124. select @id = id, @name = name from deleted; 
  125. print 'id: ' + convert(varchar, @id) + ', name: ' + @name; 
  126. --先刪除student的信息 
  127. delete student where cid = @id; 
  128. --再刪除classes的信息 
  129. delete classes where id = @id; 
  130. print '刪除[ id: ' + convert(varchar, @id) + ', name: ' + @name + ' ] 的信息成功!'
  131. go 
  132. --test 
  133. select * from student order by id; 
  134. select * from classes; 
  135. delete classes where id = 7; 
  136. # 顯示自定義消息raiserror 
  137. if (object_id('tgr_message''TR') is not null
  138. drop trigger tgr_message 
  139. go 
  140. create trigger tgr_message 
  141. on student 
  142. after insert, update 
  143. as raisError('tgr_message觸發(fā)器被觸發(fā)', 16, 10); 
  144. go 
  145. --test 
  146. insert into student values('lily', 22, 1, 7); 
  147. update student set sex = 0 where name = 'lucy'
  148. select * from student order by id; 
  149. # 修改觸發(fā)器 
  150. alter trigger tgr_message 
  151. on student 
  152. after delete 
  153. as raisError('tgr_message觸發(fā)器被觸發(fā)', 16, 10); 
  154. go 
  155. --test 
  156. delete from student where name = 'lucy'
  157. # 啟用、禁用觸發(fā)器 
  158. --禁用觸發(fā)器 
  159. disable trigger tgr_message on student; 
  160. --啟用觸發(fā)器 
  161. enable trigger tgr_message on student; 
  162. # 查詢創(chuàng)建的觸發(fā)器信息 
  163. --查詢已存在的觸發(fā)器 
  164. select * from sys.triggers; 
  165. select * from sys.objects where type = 'TR'
  166. --查看觸發(fā)器觸發(fā)事件 
  167. select te.* from sys.trigger_events te join sys.triggers t 
  168. on t.object_id = te.object_id 
  169. where t.parent_class = 0 and t.name = 'tgr_valid_data'
  170. --查看創(chuàng)建觸發(fā)器語(yǔ)句 
  171. exec sp_helptext 'tgr_message'
  172. # 示例,驗(yàn)證插入數(shù)據(jù) 
  173. if ((object_id('tgr_valid_data''TR') is not null)) 
  174. drop trigger tgr_valid_data 
  175. go 
  176. create trigger tgr_valid_data 
  177. on student 
  178. after insert 
  179. as 
  180. declare @age int
  181. @name varchar(20); 
  182. select @name = s.name, @age = s.age from inserted s; 
  183. if (@age < 18) 
  184. begin 
  185. raisError('插入新數(shù)據(jù)的age有問(wèn)題', 16, 1); 
  186. rollback tran; 
  187. end 
  188. go 
  189. --test 
  190. insert into student values('forest', 2, 0, 7); 
  191. insert into student values('forest', 22, 0, 7); 
  192. select * from student order by id; 
  193. # 示例,操作日志 
  194. if (object_id('log''U') is not null
  195. drop table log 
  196. go 
  197. create table log( 
  198. id int identity(1, 1) primary key, 
  199. action varchar(20), 
  200. createDate datetime default getDate() 
  201. go 
  202. if (exists (select * from sys.objects where name = 'tgr_student_log')) 
  203. drop trigger tgr_student_log 
  204. go 
  205. create trigger tgr_student_log 
  206. on student 
  207. after insert, update, delete 
  208. as 
  209. if ((exists (select 1 from inserted)) and (exists (select 1 from deleted))) 
  210. begin 
  211. insert into log(action) values('updated'); 
  212. end 
  213. else if (exists (select 1 from inserted) and not exists (select 1 from deleted)) 
  214. begin 
  215. insert into log(action) values('inserted'); 
  216. end 
  217. else if (not exists (select 1 from inserted) and exists (select 1 from deleted)) 
  218. begin 
  219. insert into log(action) values('deleted'); 
  220. end 
  221. go 
  222. --test 
  223. insert into student values('king', 22, 1, 7); 
  224. update student set sex = 0 where name = 'king'
  225. delete student where name = 'king'
  226. select * from log; 
  227. select * from student order by id; 

以上是本文給大家深入淺析sqlserver觸發(fā)器的全部?jī)?nèi)容,希望大家喜歡。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 阿图什市| 泗阳县| 兴和县| 海城市| 同心县| 迁安市| 凤翔县| 江川县| 德江县| 田阳县| 蓝山县| 桐城市| 行唐县| 错那县| 射阳县| 循化| 汉中市| 阳信县| 平定县| 云阳县| 耿马| 贵溪市| 巴塘县| 出国| 湘潭市| 晴隆县| 洛扎县| 贵港市| 昭觉县| 雷山县| 葫芦岛市| 赤城县| 凤凰县| 德钦县| 六枝特区| 信阳市| 高平市| 自贡市| 宁强县| 河间市| 嘉禾县|