SQL Server 触发器

﹏ヽ暗。殇╰゛Y 2021-09-17 11:20 496阅读 0赞

触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程。触发器主要是通过事件进行触发被自动调用执行的。而存储过程可以通过存储过程的名称被调用。

Ø 什么是触发器

  1. 触发器对表进行插入、更新、删除的时候会自动执行的特殊存储过程。触发器一般用在check约束更加复杂的约束上面。触发器和普通的存储过程的区别是:触发器是当对某一个表进行操作。诸如:updateinsertdelete这些操作的时候,系统会自动调用执行该表上对应的触发器。SQL Server 2005中触发器可以分为两类:DML触发器和DDL触发器,其中DDL触发器它们会影响多种数据定义语言语句而激发,这些语句有createalterdrop语句。
  2. DML触发器分为:
  3. 1 after触发器(之后触发)
  4. a insert触发器
  5. b update触发器
  6. c delete触发器
  7. 2 instead of 触发器 (之前触发)
  8. 其中after触发器要求只有执行某一操作insertupdatedelete之后触发器才被触发,且只能定义在表上。而instead of触发器表示并不执行其定义的操作(insertupdatedelete)而仅是执行触发器本身。既可以在表上定义instead of触发器,也可以在视图上定义。
  9. 触发器有两个特殊的表:插入表(instered表)和删除表(deleted表)。这两张是逻辑表也是虚表。有系统在内存中创建者两张表,不会存储在数据库中。而且两张表的都是只读的,只能读取数据而不能修改数据。这两张表的结果总是与被改触发器应用的表的结构相同。当触发器完成工作后,这两张表就会被删除。Inserted表的数据是插入或是修改后的数据,而deleted表的数据是更新前的或是删除的数据。























对表的操作

Inserted逻辑表

Deleted逻辑表

增加记录(insert)

存放增加的记录

删除记录(delete)

存放被删除的记录

修改记录(update)

存放更新后的记录

存放更新前的记录

  1. Update数据的时候就是先删除表记录,然后增加一条记录。这样在inserteddeleted表就都有update后的数据记录了。注意的是:触发器本身就是一个事务,所以在触发器里面可以对修改数据进行一些特殊的检查。如果不满足可以利用事务回滚,撤销操作。

Ø 创建触发器

  1. 语法
  2. create trigger tgr_name
  3. on table_name
  4. with encrypion –加密触发器
  5. for update...
  6. as
  7. Transact-SQL
  8. \# 创建insert类型触发器
  9. --创建insert插入类型触发器
  10. if (object_id('tgr_classes_insert', 'tr') is not null)
  11. drop trigger tgr_classes_insert
  12. go
  13. create trigger tgr_classes_insert
  14. on classes
  15. for insert --插入触发
  16. as
  17. --定义变量
  18. declare @id int, @name varchar(20), @temp int;
  19. --在inserted表中查询已经插入记录信息
  20. select @id = id, @name = name from inserted;
  21. set @name = @name + convert(varchar, @id);
  22. set @temp = @id / 2;
  23. insert into student values(@name, 18 + @id, @temp, @id);
  24. print '添加学生成功!';
  25. go
  26. --插入数据
  27. insert into classes values('5班', getDate());
  28. --查询数据
  29. select * from classes;
  30. select * from student order by id;
  31. insert触发器,会在inserted表中添加一条刚插入的记录。
  32. \# 创建delete类型触发器
  33. --delete删除类型触发器
  34. if (object_id('tgr_classes_delete', 'TR') is not null)
  35. drop trigger tgr_classes_delete
  36. go
  37. create trigger tgr_classes_delete
  38. on classes
  39. for delete --删除触发
  40. as
  41. print '备份数据中……';
  42. if (object_id('classesBackup', 'U') is not null)
  43. --存在classesBackup,直接插入数据
  44. insert into classesBackup select name, createDate from deleted;
  45. else
  46. --不存在classesBackup创建再插入
  47. select * into classesBackup from deleted;
  48. print '备份数据成功!';
  49. go
  50. --
  51. --不显示影响行数
  52. --set nocount on;
  53. delete classes where name = '5班';
  54. --查询数据
  55. select * from classes;
  56. select * from classesBackup;

delete触发器会在删除数据的时候,将刚才删除的数据保存在deleted表中。

  1. \# 创建update类型触发器
  2. --update更新类型触发器
  3. if (object_id('tgr_classes_update', 'TR') is not null)
  4. drop trigger tgr_classes_update
  5. go
  6. create trigger tgr_classes_update
  7. on classes
  8. for update
  9. as
  10. declare @oldName varchar(20), @newName varchar(20);
  11. --更新前的数据
  12. select @oldName = name from deleted;
  13. if (exists (select * from student where name like '%'+ @oldName + '%'))
  14. begin
  15. --更新后的数据
  16. select @newName = name from inserted;
  17. update student set name = replace(name, @oldName, @newName) where name like '%'+ @oldName + '%';
  18. print '级联修改数据成功!';
  19. end
  20. else
  21. print '无需修改student表!';
  22. go
  23. --查询数据
  24. select * from student order by id;
  25. select * from classes;
  26. update classes set name = '五班' where name = '5班';
  27. update触发器会在更新数据后,将更新前的数据保存在deleted表中,更新后的数据保存在inserted表中。
  28. \# update更新列级触发器
  29. if (object_id('tgr_classes_update_column', 'TR') is not null)
  30. drop trigger tgr_classes_update_column
  31. go
  32. create trigger tgr_classes_update_column
  33. on classes
  34. for update
  35. as
  36. --列级触发器:是否更新了班级创建时间
  37. if (update(createDate))
  38. begin
  39. raisError('系统提示:班级创建时间不能修改!', 16, 11);
  40. rollback tran;
  41. end
  42. go
  43. --测试
  44. select * from student order by id;
  45. select * from classes;
  46. update classes set createDate = getDate() where id = 3;
  47. update classes set name = '四班' where id = 7;
  48. 更新列级触发器可以用update是否判断更新列记录;
  49. \# instead of类型触发器
  50. instead of触发器表示并不执行其定义的操作(insertupdatedelete)而仅是执行触发器本身的内容。
  51. 创建语法
  52. create trigger tgr_name
  53. on table_name
  54. with encryption
  55. instead of update...
  56. as
  57. T-SQL
  58. \# 创建instead of触发器
  59. if (object_id('tgr_classes_inteadOf', 'TR') is not null)
  60. drop trigger tgr_classes_inteadOf
  61. go
  62. create trigger tgr_classes_inteadOf
  63. on classes
  64. instead of delete/*, update, insert*/
  65. as
  66. declare @id int, @name varchar(20);
  67. --查询被删除的信息,病赋值
  68. select @id = id, @name = name from deleted;
  69. print 'id: ' + convert(varchar, @id) + ', name: ' + @name;
  70. --先删除student的信息
  71. delete student where cid = @id;
  72. --再删除classes的信息
  73. delete classes where id = @id;
  74. print '删除[ id: ' + convert(varchar, @id) + ', name: ' + @name + ' ] 的信息成功!';
  75. go
  76. --test
  77. select * from student order by id;
  78. select * from classes;
  79. delete classes where id = 7;
  80. \# 显示自定义消息raiserror
  81. if (object_id('tgr_message', 'TR') is not null)
  82. drop trigger tgr_message
  83. go
  84. create trigger tgr_message
  85. on student
  86. after insert, update
  87. as raisError('tgr_message触发器被触发', 16, 10);
  88. go
  89. --test
  90. insert into student values('lily', 22, 1, 7);
  91. update student set sex = 0 where name = 'lucy';
  92. select * from student order by id;
  93. \# 修改触发器
  94. alter trigger tgr_message
  95. on student
  96. after delete
  97. as raisError('tgr_message触发器被触发', 16, 10);
  98. go
  99. --test
  100. delete from student where name = 'lucy';
  101. \# 启用、禁用触发器
  102. --禁用触发器
  103. disable trigger tgr_message on student;
  104. --启用触发器
  105. enable trigger tgr_message on student;
  106. \# 查询创建的触发器信息
  107. --查询已存在的触发器
  108. select * from sys.triggers;
  109. select * from sys.objects where type = 'TR';
  110. --查看触发器触发事件
  111. select te.* from sys.trigger_events te join sys.triggers t
  112. on t.object_id = te.object_id
  113. where t.parent_class = 0 and t.name = 'tgr_valid_data';
  114. --查看创建触发器语句
  115. exec sp_helptext 'tgr_message';
  116. \# 示例,验证插入数据
  117. if ((object_id('tgr_valid_data', 'TR') is not null))
  118. drop trigger tgr_valid_data
  119. go
  120. create trigger tgr_valid_data
  121. on student
  122. after insert
  123. as
  124. declare @age int,
  125. @name varchar(20);
  126. select @name = s.name, @age = s.age from inserted s;
  127. if (@age < 18)
  128. begin
  129. raisError('插入新数据的age有问题', 16, 1);
  130. rollback tran;
  131. end
  132. go
  133. --test
  134. insert into student values('forest', 2, 0, 7);
  135. insert into student values('forest', 22, 0, 7);
  136. select * from student order by id;
  137. \# 示例,操作日志
  138. if (object_id('log', 'U') is not null)
  139. drop table log
  140. go
  141. create table log(
  142. id int identity(1, 1) primary key,
  143. action varchar(20),
  144. createDate datetime default getDate()
  145. )
  146. go
  147. if (exists (select * from sys.objects where name = 'tgr_student_log'))
  148. drop trigger tgr_student_log
  149. go
  150. create trigger tgr_student_log
  151. on student
  152. after insert, update, delete
  153. as
  154. if ((exists (select 1 from inserted)) and (exists (select 1 from deleted)))
  155. begin
  156. insert into log(action) values('updated');
  157. end
  158. else if (exists (select 1 from inserted) and not exists (select 1 from deleted))
  159. begin
  160. insert into log(action) values('inserted');
  161. end
  162. else if (not exists (select 1 from inserted) and exists (select 1 from deleted))
  163. begin
  164. insert into log(action) values('deleted');
  165. end
  166. go
  167. --test
  168. insert into student values('king', 22, 1, 7);
  169. update student set sex = 0 where name = 'king';
  170. delete student where name = 'king';
  171. select * from log;
  172. select * from student order by id;

本文出自:http://www.cnblogs.com/hoojo/archive/2011/07/20/2111316.html

发表评论

表情:
评论列表 (有 0 条评论,496人围观)

还没有评论,来说两句吧...

相关阅读

    相关 SQL Server 触发器

    触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程。触发器主要是通过事件进行触发被自动调用执行的。而存储过程可以通过存储过程的名称被调用。 Ø 什么是触发器

    相关 SQL Server触发器

    简单介绍:     触发器其实是一种特殊的存储过程,它只有在特定的事件发生时自动执行。存储过程和触发器都是SQL语句和流程控制语句的集合,存储过程通过存储过程的名字被直接

    相关 SQL server 触发器示例

    概念 触发器是一种特殊类型的存储过程,不由用户直接调用。创建触发器时会对其进行定义,以便在对特定表或列作特定类型的数据修改时执行。 触发器可以查询其他表,而且可以包含复

    相关 sql server 触发器详解

    触发器: 概念: 触发器是一个在修改制定表中的数据时执行的存储过程,它的执行不由程序调用也不是手工启动, 触发器主要通过事件进行触发而被执行 触发器和存储过程的

    相关 SQL Server触发器

    SQL Server触发器是特殊的[存储过程][Link 1],它们会自动执行以响应数据库对象,数据库和服务器事件。 SQL Server提供三种类型的触发器: 数据操

    相关 SQL Server 触发器

    触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程。触发器主要是通过事件进行触发被自动调用执行的。而存储过程可以通过存储过程的名称被调用。 Ø 什么是触发器