数据库系统概论(超详解!!!)第六节 触发器

数据的完整性是为了防止数据库中存在不符合语义的数据。

一种是在定义表时声明数据完整性,称为声明完整性。

另一种是在服务器端编写触发器来实现,称为过程完整性。完成比参照完整性约束和CHECK约束更复杂的数据约束。

1、触发器概述

触发器是一种特殊的存储过程,它是在执行某些特定的T-SQL语句时自动执行的一种存储过程。   

不需要由用户调用执行,而是当用户对表中的数据进行UPDATE、INSERT或DELETE操作时自动触发执行的。

在 SQL Server  系统中,按照触发事件的不同可以把提供的触发器分成两大类型 : DML 触发器和 DDL 触发器。

1.DDL触发器

DDL 触发器当服务器或者数据库中发生数据定义语言(DDL)事件时将被调用。如果要执行以下操作,可以使用 DDL 触发器: 要防止对数据库架构进行某些更改 ;希望数据库中发生某种情况以响应数据库架构中的更改; 要记录数据库架构中的更改或者事件。

2.DML  触发器

DML 触发器是当数据库服务器中发生数据操作语言(DML)事件时要执行的操作。

通常所说的 DML 触发器主要包括三种:INSERT 触发器、UPDATE 触发器、DELETE 触发器。

DML 触发器可以查询其他表,还可以包含复杂的 Transact-SQL 语句。

SQL  Server提供以下两种触发方式:     

后触发:在触发操作(INSERT、 UPDATE或DELETE)执行完成,并处理过所有约束后激活触发器,这种方式称做后触发。如果触发操作违反约束条件,将导致事务回滚,这时就不会执行后触发器。但在视图上不能采用后触发方式定义触发器。     

替代触发:当触发操作发生时,数据库引擎首先创建临时inserted表和deleted表,之后,SQL  Server停止执行通常的操作,而转去执行替代触发器。

2、Deleted表和Inserted表

在触发器执行的时候,系统会产生两个临时表:inserted 表和deleted 表。

它们的结构和触发器所在的表的结构相同,SQL Server 自动创建和管理这些表。

可以使用这两个临时的驻留内存的表测试某些数据修改的效果及设置触发器操作的条件,然而不能直接对表中的数据进行更改。

在对具有触发器的表(触发器表)进行操作时,其操作过程:

执行INSERT操作,插入到触发器表中的新行被自动的插入到Inserted 表中。

执行DELETE操作,从触发器表中删除的行被自动的插入到Deleted 表中。

执行UPDATE操作,先从触发器表中删除旧行,然后再插入新行。其中被删除的旧行被插入到Deleted 表中,插入的新行被插入到Inserted 表中。

DELETED表存储DELETE和UPDATE语句所影响的行的副本。在执行DELETE或UPDATE语句时,行从触发器表中删除,并传输到DELETED表中。DELETED表和触发器表通常没有相同的行。

INSERTED表存储INSERT和UPDATE语句所影响的行的副本。在一个插入或更新操作中,新建行也同时添加到INSERTED表和触发器表中。INSERTED表中的行是触发器表中新行的副本。

3、定义触发器

建立触发器
CREATE TRIGGER 触发器名称
ON Table| view              //是在其上执行触发器的表或视图,有时称为触发器表或触发器视图
{ FOR | AFTER | INSTEAD OF }   //指定触发器触发的时机,其中 FOR 也创建 AFTER 触发器
{ [ INSERT ] [ , ] [ DELETE ] [ , ] [UPDATE ] }                 //是指定在表或视图上执行哪些数据修改语句时将触发触发器的关键字。必须至少指定一个选项。在触发器定义中允许使用以任意顺序组合的这些关键字。如果指定的选项多于一个,需用逗号分隔这些选项
AS SQL 语句 [ ... n ]     //Sql_statement 指定触发器所执
行的 T-SQL 语句

After触发器在一个Insert,Update或Deleted语句之后执行,进行约束检查等动作都在After触发器被激活之前发生。After触发器只能用于表。

如果一个Insert﹑update或者delete语句违反了约束,那么After触发器不会执行,因为对约束的检查是在After触发器被激动之前发生的。所以After触发器不能超越约束。

Instead of触发器用于替代引起触发器执行的T-SQL语句。除表之外,Instead of 触发器也可以用于视图,用来扩展视图可以支持的更新操作。

Instead of 触发器可以取代激发它的操作来执行。它在Inserted表和Deleted表刚刚建立,其它任何操作还没有发生时被执行。因为Instead of 触发器在约束之前执行,所以它可以对约束进行一些预处理。

一个表或视图的每一个修改动作(insert,update和delete)都可以有一个instead of 触发器,一个表的每个修改动作都可以有多个After触发器。

1、INSTEAD OF 触发器——对数据增删改时,只执行触发器中的操作,而不执行( UPDATE、INSERT、DELETE )操作。
例子:Create  trigger 学生表修改通知On studentinstead of  insertAs Print '学生表发生了变化'select * from deletedselect * from insertedselect * from studentgo测试:Insert studentValues('201215016','刘席','男',16,'IS')2、AFTER触发器——数据增删改操作被临时存放,然后与触发器中的操作一起提交,也可以检查错误从而回退。相当于增删改操作与触发器中的操作构成一个事务。
例子:USE student
IF EXISTS (SELECT name FROM sysobjects
WHERE name = '学生表修改通知' AND type = 'TR')
DROP TRIGGER 学生表修改通知
GO
Create  trigger 学生表修改通知
On student
For insert,update  
As 
Print '学生表发生了变化'
select * from deleted
select * from inserted
select * from student
go
--delete from 学生表where 姓名='刘席'
--DROP TRIGGER 学生表修改通知
插入记录Insert studentValues(‘20180016’,‘刘席’,‘男’,’20040205,‘信息安全')
定义一个触发器,如果在学生表中插入记录,则提示“欢迎新同学”。CREATE TRIGGER welcome_studentON studentAFTER INSERTAS PRINT '欢迎新同学!'GO创建一个名为 grade_warn 的触发器,当成绩大于100 时,就提示‘成绩不能大于100分’。然后执行 sp_helptrigger 列出表 SC 中触发器的相关信息。
USE SCC
IF OBJECT_ID('grade_warn','TR') IS  NOT  NULLDROP TRIGGER grade_warn;
GOCREATE TRIGGER grade_warnON SCFOR INSERT, UPDATE AS declare @gg intSELECT @gg=grade from insertedif @gg>100BEGINPRINT '成绩不能超过100分‘ROLLBACKENDEXEC sp_helptrigger SC.限制删除SC表中成绩不及格学生的修课记录。CREATE TRIGGER tri_del_gradeON SC FOR DELETEASIF EXISTS(SELECT * FROM DELETED    WHERE Grade < 60)ROLLBACK 限制将SC表中不及格学生的成绩改为及格。create trigger tri_update_grade
on sc for update
as if update(grade)if exists(select * from inserted,deletedwhere inserted.sno=deleted.sno and inserted.grade>=60 and deleted.grade<60)begin	print '不能将不及格的成绩改为及格'rollbackend学生退学了要自动删除学生的选课信息
CREATE TRIGGER  t_delS ON  S  
instead of DELETE 
AS 	delete   from scfrom deletedwhere sc.sno=deleted.sno delete from sfrom deletedwhere s.sno=deleted.sno测试:  delete from s where sno='95001'创建一个名为tri_Insert_S的触发器,测试该触发器的执行情况,并给出实验结果。当插入的新记录中Sage的值不是18至25之间的数值时,就激活该触发器,撤销该插入操作,并给出错误提示。
use SCC
go 
create trigger tri_Insert_S on Student
after insert
as
if exists (select * from insertedwhere Sage>=18 and Sage<=25)print'添加成功!'
elsebegin print'无法添加!'rollback transactionend
go
insert into Student values(‘201205221','黄丽','女',26,'计算机')
insert into Student values(‘201205222’,’黄月英','女',20,'计算机')
select * 
from Student
go创建一个名为tri_Update_SC的触发器,要求:(1)首先判断数据库中是否已经存在名为tri_Update_SC的触发器,如果存在,首先删除,再创建。(2)当试图修改SC表中的学生成绩时,给出不能随便修改成绩的信息提示。
use SCC
go 
if exists(select name from sysobjectswhere name='tri_Update_SC' and type='TR')begin drop trigger tri_Update_SCend
else print'不存在该触发器,可新建。'
Go
create trigger tri_Update_SC on SC
after update
asif update(GRADE)beginprint'不能随意修改成绩!'rollback transactionend
goupdate SC 
set GRADE=90
Go禁用tri_Update_SC触发器,并演示禁用该触发器后Update的执行情况。
use scc
go 
alter table SC disable trigger tri_Update_SC
update SC
set Score='95'
where Sno='S1' and Cno='C3'
print'修改成功!'
select * 
from SC
Go创建一个名为tri_Delete_C 的触发器,实现:删除一门课程时候,首先判断该课程有否有人选,如果有人选,则不能删除并通过测试数据验证该触发器的执行情况。use SCC
go
create trigger tri_Delete_C on Course
instead of delete
as 
if(exists (select * from SC,deletedwhere SC.Cno=deleted.Cno))beginrollback transactionprint'该课程无法删除!'end
elsebegindelete from Course where Cno in( select Cno from deleted)end 
go
delete from Course
where Cno='C1'
go 

4、查看触发器

若要查看某一特定表上现有的触发器,使用存储过程:

sp_helptrigger  数据表名

若要查看已经建好的触发器代码。使用存储过程:

sp_helptext   触发器名

使用系统存储过程sp_help,sp_helptext,sp_helptrigger查看触发器相关信息。给出显示结果。
use SCC
go
exec sp_help 'tri_Insert_S'
exec sp_helptext 'tri_Insert_S'
exec sp_helptrigger 'S'
go

5、删除触发器

修改触发器语法格式:
ALTER TRIGGER 触发器名称
ON 表名
{ FOR | AFTER | INSTEAD OF } 
{ [ INSERT ] [ , ] [ DELETE ] [ , ] [UPDATE ] }
AS SQL 语句 [ ... n ] 删除触发器语法格式:
DROP TRIGGER 触发器名 [ , ... n ]例:删除tri_grade触发器。
DROP TRIGGER tri_grade 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/902.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣经典150题第三十三题:最小覆盖子串

目录 解题思路与实现 - 最小覆盖子串问题描述示例解题思路算法实现复杂度分析测试与验证总结 感谢阅读&#xff01; 解题思路与实现 - 最小覆盖子串 问题描述 给定一个字符串 s 和一个字符串 t&#xff0c;返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字…

图文教程 | 2024年最新Typora激活使用教程合集

前言 汇总一下网上的三种方法。 &#x1f4e2;博客主页&#xff1a;程序源⠀-CSDN博客 &#x1f4e2;欢迎点赞&#x1f44d;收藏⭐留言&#x1f4dd;如有错误敬请指正&#xff01; 关于安装教程&#xff1a;http://t.csdnimg.cn/SCIQ8http://t.csdnimg.cn/SCIQ8自行跳转安装 一…

35. 【Android教程】视频页面:ViewPager

ViewPager 是一种可以让用户通过左右滑动来切换页面的控件&#xff0c;通过它我们可以展示超过屏幕尺寸大小的内容&#xff0c;在某种程度上它可以说是实现多页面的最佳方式&#xff0c;同时 ViewPager 还支持任意动态的添加/删除页面。比如我们可以将不同的类别的内容分别放在…

java 创建和请求sse服务

主要依赖 <!--spring-boot父工程--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.2.RELEASE</version></parent><dependency><gro…

AOP基础

一、AOP概述 AOP&#xff1a;Aspect Oriented Programming&#xff08;面向切面编程、面向方面编程&#xff09;&#xff0c;其实就是面向特定方法编程。 使用场景&#xff1a;①记录操作日志&#xff1b;②权限控制&#xff1b;③事务管理等。 优势&#xff1a;①代码无侵入…

学校管网的仿写

工字形布局完成 效果 代码部分 在这里插入代码片 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport…

密码学 | Random Oracle 随机预言机

​ &#x1f951;原文&#xff1a;究竟什么才是随机预言机呢&#xff1f; - 玄星的回答 &#x1f951;答主指出&#xff1a; 英文维基明明对 随机预言机 给出了两个完全不同的理解&#xff0c;但这两个理解之间的连接词却是 “Stated differently”&#xff0c;即 “换句话说…

Unity ECS

一&#xff1a;前言 ECS与OOP不同&#xff0c;ECS是组合编程&#xff0c;而OOP的理念是继承 E表示Entity&#xff0c;每个Entity都是一个有唯一id的实体。C表示Component&#xff0c;内部只有属性&#xff0c;例如位置、速度、生命值等。S表示System&#xff0c;驱动实体的行为…

npm i 依赖下载失败

git config --global url."https://".insteadOf git://解决npm install 报错 npm ERR code 128 Permission denied_please make sure you have the correct access right-CSDN博客

怎么把相机储存卡里的照片导出来?介绍两种方法

随着摄影技术的不断发展和普及&#xff0c;相机已成为我们记录生活、捕捉美好瞬间的设备。然而&#xff0c;对于许多摄影爱好者来说&#xff0c;如何将相机储存卡里的照片安全、高效地导出到电脑或其他设备中&#xff0c;却成为了一个令人头疼的问题。本文将为您详细介绍从相机…

SpringCloud之服务远程调用(OpenFeign)

1.OpenFeign OpenFeign是一个声明式的http客户端&#xff0c;作用是基于SpringMVC的常见注解&#xff0c;实现更便捷的http请求发送 2.OpenFeign使用步骤 &#xff08;1&#xff09;导入依赖坐标 <!--OpenFeign--><dependency><groupId>org.springframewo…

c++IO

前言 大家好&#xff0c;我是jiantaoyab&#xff0c;本篇文章给大家介绍c中文件操作。 先回忆一下c语言文件操作 void Test_c_bin() {//二进制写ServerInfo info { "127.0.0.1", 8080 };FILE* fout fopen("test.bin", "wb");fwrite(&in…

Rust常用特型之Sized特型

在Rust标准库中&#xff0c;存在很多常用的工具类特型&#xff0c;它们能帮助我们写出更具有Rust风格的代码。 一个Sized 类型是指 它所有的值在内存中有相同的大小&#xff0c;反之没有相同大小就是UnSized 类型。 Rust中几乎所有的类型都是Sized的&#xff0c;例如每个u64在…

18 统计网站每日的访问次数

1.将竞赛的数据上传HDFS,查看数据的格式 通过浏览器访问hdfs,查看该文档前面的部分数据 每条数据的字段值之间使用逗号隔开的 &#xff0c;最终时间是第五个自动&#xff0c;获取第五个字段值的中的年月日。 2.通过Idea创建项目mr-raceData ,基础的配置 修改pom.xml,添加依赖 …

Spring Boot集成fastdfs快速入门Demo

1.什么是fastdfs FastDFS 是一个开源的高性能分布式文件系统&#xff08;DFS&#xff09;。它的主要功能包括&#xff1a;文件存储&#xff0c;文件同步和文件访问&#xff0c;以及高容量和负载平衡。主要解决了海量数据存储问题&#xff0c;特别适合以中小文件&#xff08;建议…

从零开始搭建网站(第二天)

今天把之前的htmlcssjs项目迁移过来&#xff0c;直接使用tspiniavue3vite组合&#xff0c;搭建过程可以看从零开始搭建性能完备的网站-思路过程&#xff08;1&#xff09;_自己架设一个芯参数网站-CSDN博客。之后安装一下volar扩展。迁移过来使用Vue重构时发现之前使用的左右两…

【Python】如何利用MinHash和LSH进行大规模文本数据去重

十年之前 我不认识你 你不属于我 我们还是一样 陪在一个陌生人左右 走过渐渐熟悉的街头 十年之后 我们是朋友 还可以问候 只是那种温柔 再也找不到拥抱的理由 情人最后难免沦为朋友 &#x1f3b5; 刘若英《十年》 去重逻辑实现 数据准备&#xff1a;在内…

学习-官方文档编辑方法

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

电感与磁珠

电感是什么&#xff1f; 电感会通过产生感应电动势的方式来阻碍电流的变化&#xff0c;电流变化率越大&#xff0c;产生的感应电动势越大阻碍电流效果越明显。 [一]品质因数Q: 电感的品质因数Q值定义&#xff1a;电感的Q值也叫作品质因数&#xff0c;其为无功功率除以有功功率…

API请求报错 Required request body is missing问题解决

背景 在进行调用的时候&#xff0c;加载方法&#xff0c;提示以下错误 错误信息如下&#xff1a; {"code": 10001,"msg": "Required request body is missing: XXX","data": null,"extra": null }Required request body…