SQL Server研习录(25)——sql server触发器、instered表和deleted表知识详解及示例分析

  • 版权声明
    • 一、创建测试数据
    • 二、触发器
      • 1、基本知识
      • 2、触发器的分类
        • (1)DML触发器
        • (2)DDL触发器
        • (3)登录触发器
      • 3、instered表和deleted表
    • 二、编写触发器及示例
      • 1、创建触发器
        • (1)基本语法
        • (2)delete触发器示例
        • (3)update触发器示例
        • (4)insert触发器示例
      • 2、修改触发器
      • 3、删除触发器

版权声明

  • 本文原创作者:清风不渡
  • 博客地址:https://blog.csdn.net/WXKKang

一、创建测试数据

  首先我们创建测试数据以帮助我们学习本篇内容,共有两张表:课程表(course)与学生表(student),其中学生表中的course_id字段为course的外键,代码如下:

USE [demo]-- 创建course表
CREATE TABLE course(course_id varchar(50) PRIMARY KEY,course_name varchar(50)
)
GO-- 创建student表
CREATE TABLE student(student_id varchar(50) PRIMARY KEY,student_name varchar(50),course_id varchar(50) FOREIGN KEY REFERENCES course(course_id)
)
GO-- 插入数据
INSERT INTO course (course_id,course_name)
VALUES
('C001','语文'),
('C002','数学'),
('C003','英语')
GOINSERT INTO student (student_id,student_name,course_id)
VALUES
('S001','Lucy','C001'),
('S002','Jack','C002'),
('S003','Jane','C003'),
('S004','Jameson','C001')
GO

二、触发器

1、基本知识

  为了更好的强制业务规则和保证数据的完整性,sql server为我们提供了两种机制,它们分别是约束和触发器,本篇我们就来学习触发器,在触发器中,我们可以查询其他表,也可以包含复杂的Transact-SQL语句,并且可以将触发器和触发它的语句作为可在触发器内回滚的单个事务对待。如果检测到严重错误(例如,磁盘空间不足),则整个事务即自动回滚
  说到这里,我想到了数据库中的另外一个东西——存储过程,它们两个真的是太像了,几乎可以说存储过程可以做什么触发器就可以做什么,所以我们也可以把触发器称作是一种特殊的存储过程,那么,既然它是特殊的存储过程,那它到底特殊在哪里呢?触发器与存储过程最大的不同就是:它是与表事件(insert、delete、update)相关的存储过程,它的执行既不是由程序调用的,也不是由手工调用的,而是由事件来触发的,这就是它的神奇之处,比如当我们对一个表进行操作(insert、delete、update)时就会激活它执行,这就满足了普通存储过程所做不到的一些需求,是不是特别棒呢

2、触发器的分类

  sql server包括三种常规类型的触发器:DML触发器、DDL触发器和登录触发器

(1)DML触发器

  当数据库中表里面的数据发生变化时,例如进行insert、update、delete操作时,如果我们对该表创建了对应的触发器,那么对应的触发器在数据发生对应变化的时候就会自动执行。DML触发器的主要作用为:强制执行业务规则,以及扩展sql server的约束,默认值等。因为约束只能约束同一个表中的数据,而我们在触发器中可以执行任意sql语句,当然可以将其他表中想约束的任意字段与本表中相对应的字段联合在一起来约束
  DML触发器分为:
  1、after触发器(执行对应语句之后触发):insert触发器、update触发器以及delete触发器——只能定义在表上
  2、instead of(执行之前触发):定义了instead of触发器则表示并不执行其定义的操作(insert、update、delete)而仅是执行触发器本身——可以在表上定义,也可以在视图上定义

(2)DDL触发器

  在sql server 2005中新增了DDL触发器,它主要用于审核与规范对数据库表中表、触发器、视图等结构上的操作,比如在修改表、新增表、创建列、修改列等可以影响数据库结构发生变化的时候执行的,我们主要是用它来记录数据库的修改过程,以及限制程序员对数据库的修改,比如可以限制不允许删除某些指定的表等

(3)登录触发器

  登录触发器是为了响应Login事件而激发的存储过程,与sql server示例建立用户会话时将引发此事件,登录触发器将在登录的身份验证阶段完成之后且用户会话实际建立之前激发。因此,来自触发器内部且通常将到达用户的所有信息(例如错误消息和来自print语句的消息)会传送到sql server错误日志。如果身份验证失败,将不再激发登录触发器

3、instered表和deleted表

  触发器有两个特殊的表:instered表和deleted表,这两张是逻辑表也是虚表。由系统在内存中创建者两张表,不会存储在数据库中。而且两张表的都是只读的,只能读取数据而不能修改数据。这两张表的结果总是与被该触发器应用的表的结构相同,当触发器完成工作后,这两张表就会被删除。Inserted表的数据是插入或是修改后的数据,而deleted表的数据是更新前的或是删除的数据,它们具体存储的数据与对应的表数据操作如下:

表操作 Inserted逻辑表 Deleted逻辑表
新增记录(insert) 存放增加的记录
修改记录(update) 存放更新后的记录 存放更新前的记录
删除记录(delete) 存放被删除的记录

  为什么我们在对表中的数据执行更新记录的时候,instered表和deleted表中都会有数据呢?因为我们在对表中数据进行更新的操作,实际上是先删除这条记录,然后在新增一条记录,因为这样,所以instered表和deleted表中都会有数据

二、编写触发器及示例

  现在,我们就结合示例来学习一下触发器的具体操作

1、创建触发器

(1)基本语法

  创建触发器的语法如下:

CREATE TRIGGER [触发器名称] ON [表名称]FOR UPDATE -- 或DELETE、或INSERT
AS --Transact-SQL(业务逻辑代码)
(2)delete触发器示例

  现在我们根据上面的测试数据来创建一个触发器,已知student表中的course_id为course表的外键,那么我们要实现这样一个需求,当学生表(student)中没有学生学习某一门课程的时候,我们将这门课程自动删除。这时,我们就需要创建一个delete触发器,代码如下:

-- 创建studnet表的触发器
CREATE TRIGGER [dbo].[student_delete] ON [dbo].[student]
FOR DELETEASDECLARE @course_id VARCHAR(50)
SELECT @course_id = course_id FROM deleted
IF EXISTS (SELECT 1 FROM student WHERE course_id = @course_id)
BEGINPRINT 'student表中存在学习该课程的学生'
END
ELSE
BEGINPRINT 'student表中不存在学习该课程的学生' DELETE course where course_id = @course_idPRINT 'course表中相关数据已删除'
END

  现在我们对此触发器做一个测试,我们从上面的测试数据知道,Lucy和Jameson都学习了语文这门课程(course_id为“C001”),现在Lucy由于转班去了别的班级,我们需要将此学生的信息删除,代码如下:

delete student where student_id = 'S001'

  执行结果如下:

  我们知道,有两名学生学习了语文,现在一位同学不在这个班级了,但是还有一名学生在学习语文这门课程,按照我们的预想,course表中课程名为语文的这条记录不应该被删除,现在我们来验证我们的预想,执行以下代码:

SELECT * FROM student
SELECT * FROM course


  我们可以看到Lucy的记录删掉了,但是语文这门课程还在,结果与我们预想的一样
  后来,Jamson因为考了七次都没有考过语文,心灰意冷的连夜买站票离开了这个城市,我们需要将他的记录也清除掉,代码如下:

delete student where student_id = 'S004'

  执行结果如下:

  可以看出,课程表中相关的内容也被删除掉了,我们可以验证一下,查询结果如下:

  确实,不仅删除了student表中名为Jamson的记录,也删除了course表中课程名为语文的课程记录,说明我们的触发器满足了我们的需求

(3)update触发器示例

  我们首先给student表中添加任课教师列(course_teacherName),然后为在表中的数据添加相关任课教师的名称,代码如下:

ALTER TABLE course
ADD course_teacherName varchar(50)
GOUPDATE course SET course_teacherName =
CASE WHEN course_id = 'C002' THEN '邢道荣'
WHEN course_id = 'C003' THEN '潘凤' END
GO

  现在我们有这样一个需求,就是课程的任课教师不允许修改,那么我们就需要创建一个对应的update触发器,代码如下:

-- 创建studnet表的触发器
CREATE TRIGGER [dbo].[course_update] ON [dbo].[course]
FOR UPDATEASIF (UPDATE(course_teacherName))
BEGINraiserror('任课老师不允许修改!',16,1);rollback tran;
END

  创建好了之后,我们再来更新任课教师的内容,代码如下:

UPDATE course SET course_teacherName = '许褚' WHERE course_id = 'C002'

  执行结果如下:

  可以看到,这个触发器满足了我们的需求

(4)insert触发器示例

  需求,我们需要在course表中添加更新时间字段(update_time),当我们插入学生的时候,就要对相应的该课程的时间进行更新,代码如下:

-- 为course表添加字段
ALTER TABLE course
ADD update_time varchar(50)
GO
-- 创建student表的触发器
CREATE TRIGGER [dbo].[course_insert] ON [dbo].[student]
FOR insertASDECLARE @course_id varchar(50)
SELECT @course_id = course_id FROM inserted
UPDATE course SET update_time = CONVERT(VARCHAR(50),GETDATE(),21) WHERE course_id = @course_id
PRINT '相应课程的修改时间已更新'

  下面我们来测试一下,为student表中新添加一个学生,代码如下:

INSERT INTO student VALUES ('S004','张三','C003')

  执行结果如下:

  现在我们来看course表中对应字段是否发生更新,查询结果如下:

  可以看到,course表中对应的字段发生了更新,满足了我们的需求

2、修改触发器

  修改触发器我们既可以在SSMS管理工具中找到该表并展开,然后展开触发器之后选中对应的触发器右键单击修改,这样就可以修改,或者可以使用T-SQL代码修改,只需将关键字CREATE改为ALTER即可,代码结构:

ALTER TRIGGER [触发器名称] ON [表名称]FOR UPDATE -- 或DELETE、或INSERT
AS --Transact-SQL(业务逻辑代码)

3、删除触发器

  同样,如果需要删除触发器我们也可以在SSMS管理工具中找到该触发器,然后右键删除即可,也可以使用T-SQL代码实现删除,代码如下:

drop trigger 触发器名称

  还有像禁用、启用等操作都可以通过SSMS管理工具去简单的实现,大家不妨试试哟

SQL Server研习录(25)——sql server触发器、instered表和deleted表知识详解及示例分析相关推荐

  1. SQL Server研习录(23)——RAISERROR()函数

    SQL Server研习录(23)--RAISERROR函数 版权声明 一.RAISERROR()函数 1.基本语法 版权声明 本文原创作者:清风不渡 博客地址:https://blog.csdn.n ...

  2. SQL Server研习录(08)——LEFT()函数

    SQL Server研习录(08)--LEFT函数 版权声明 一.LEFT()函数 1.基本语法 2.示例 版权声明 本文原创作者:清风不渡 博客地址:https://blog.csdn.net/WX ...

  3. SQL Server研习录(29)——sql server 设置列自增长

    SQL Server研习录(29)--sql server 设置列自增长 版权声明 一.设置列自增长 1.创建表时 2.创建表后 版权声明 本文原创作者:清风不渡 博客地址:https://blog. ...

  4. SQL Server研习录(24)——Windows Server 2012 R2安装数据库时提示KB2919355安装问题解决

    SQL Server研习录(24)--Windows Server 2012 R2安装数据库时提示KB2919355安装问题解决 版权声明 一.问题描述 二.解决办法 版权声明 本文原创作者:清风不渡 ...

  5. SQL Server研习录(22)——ABS()函数

    SQL Server研习录(22)--ABS函数 版权声明 一.ABS()函数 1.基本语法 2.示例 版权声明 本文原创作者:清风不渡 博客地址:https://blog.csdn.net/WXKK ...

  6. SQL server触发器 inserted表和deleted表用法

    inserted表和deleted表用于存放对表中数据行的修改信息,他们是触发器执行时自动创建的,放在内存中,是临时表.当触发器工作完成,它们也被删除.它们是只读表,不能向它们写入内容. insert ...

  7. SQL全方位攻略:5. SQL “方言”大比拼:Oracle、MySQL、PostgreSQL限制检索行数语法详解(分页查询)

    系列文章目录 SQL全方位攻略:1.数据库介绍 SQL全方位攻略:2.SQL介绍 SQL全方位攻略:3.SQL标准 SQL全方位攻略:4. 标准SQL和SQL"方言" 文章目录 系 ...

  8. mysql inserted表_触发器中的inserted表和deleted表

    触发器语句中使用了两种特殊的表:deleted 表和 inserted 表.Microsoft? SQL Server 2000 自动创建和管理这些表.可以使用这两个临时的驻留内存的表测试某些数据修改 ...

  9. 在创建触发器时出现不能在 'inserted' 表和 'deleted' 表中使用 text、ntext 或 image 列...

    1. 不能在 'inserted' 表和 'deleted' 表中使用 text.ntext 或 image 列 在 create trigger trg on t1 for update 改成 cr ...

  10. 鸿蒙之境的称号,神都夜行录鸿蒙之境80级古都凶煞打法技巧详解

    神都夜行录鸿蒙之境80级古都凶煞如何打呢?相信不少玩家对此还不是很清楚,下面小编就给大家带来了神都夜行录鸿蒙之境80级古都凶煞打法技巧详解,一起来看看吧~! 神都夜行录鸿蒙之境80级古都凶煞打法攻略 ...

最新文章

  1. 微信小程序API·目录
  2. python美多商城项目百度网盘_美多商城项目(七)
  3. pat1035. Password (20)
  4. LeetCode 241. 为运算表达式设计优先级(动态规划)
  5. sqlerver 字符串转整型_字符串转换成整型并求和
  6. c语言的数组在栈区还是,用数组实现栈的功能的C语言代码?
  7. python磁盘空间_python3实现磁盘空间监控
  8. threading.Event
  9. Maven打jar包的三种方式
  10. Thinking in Java Chapter 14
  11. net.sf.json与fastjson两种jar包的使用
  12. pythonpdf识别文字_python – 从PDF中读取字体颜色信息
  13. Js 嵌套if选择结构
  14. 蓝桥杯:国二选手经验贴 附蓝桥杯历年真题
  15. 0x00000004 因果推理 —— 入门学习笔记
  16. hive分隔符_hive默认分隔符
  17. Word标题样式前编号显示黑块
  18. ‘home‘ has a default child route. When navigating to this named route (:to=“{name: ‘home‘“), the def
  19. 基于实例分割方法的端到端车道线检测 论文+代码解读
  20. 洛谷 P1348 Couple number

热门文章

  1. Ubuntu安装N卡驱动
  2. cocos2d-x 移动MM平台SDK接入
  3. 把“SC”表中“叶平”老师教的课的成绩都更改为此课程的平均成绩
  4. Xcode8 10大新特性
  5. 企业微信:上传图片获取永久url --Java
  6. 手把手写深度学习(3)——用RNN循环神经网络自动生成歌词之理论篇
  7. 论如何成为技术大牛,GitHub中国区前20名详解
  8. kafka消息堆积及分区不均匀的解决方案
  9. WingIDE6破解方法
  10. 王之泰201771010131《面向对象程序设计(java)》第十周学习总结