SqlServer基础之(触发器)
概念:
触发器(trigger)是SQL server 提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,当对一个表进行操作( insert,delete, update)时就会激活它执行。触发器经常用于加强数据的完整性约束和业务规则等。 触发器可以从 DBA_TRIGGERS ,USER_TRIGGERS 数据字典中查到。
触发器和存储过程的区别:
触发器与存储过程的区别是运行方式的不同,触发器不能执行EXECUTE语句调用,而是在用户执行Transact-SQL语句时自动触发执行而存储过程需要用户,应用程序或者触发器来显示地调用并执行。
一:触发器的优点
1.触发器是自动的。当对表中的数据做了任何修改之后立即被激活。
2.触发器可以通过数据库中的相关表进行层叠修改。
3.触发器可以强制限制。这些限制比用CHECK约束所定义的更复杂。与CHECK约束不同的是,触发器可以引用其他表中的列。
二:触发器的作用
触发器的主要作用就是其能够实现由主键和外键所不能保证的复杂参照完整性和数据的一致性,它能够对数据库中的相关表进行级联修改,提高比CHECK约束更复杂的的数据完整性,并自定义错误消息。触发器的主要作用主要有以下接个方面:
- 强制数据库间的引用完整性
- 级联修改数据库中所有相关的表,自动触发其它与之相关的操作
- 跟踪变化,撤销或回滚违法操作,防止非法修改数据
- 返回自定义的错误消息,约束无法返回信息,而触发器可以
- 触发器可以调用更多的存储过程
三:触发器的分类
SqlServer包括三种常规类型的触发器:DML触发器、DDL触发器和登录触发器。
1.DML(数据操作语言,Data Manipulation Language)触发器
DML触发器是一些附加在特定表或视图上的操作代码,当数据库服务器中发生数据操作语言事件时执行这些操作。SqlServer中的DML触发器有三种:
- insert触发器:向表中插入数据时被触发;
- delete触发器:从表中删除数据时被触发;
- update触发器:修改表中数据时被触发。
当遇到下列情形时,应考虑使用DML触发器:
- 通过数据库中的相关表实现级联更改
- 防止恶意或者错误的insert、update和delete操作,并强制执行check约束定义的限制更为复杂的其他限制。
- 评估数据修改前后表的状态,并根据该差异才去措施。
2.DDL(数据定义语言,Data Definition Language)触发器
DDL触发器是当服务器或者数据库中发生数据定义语言(主要是以create,drop,alter开头的语句)事件时被激活使用,使用DDL触发器可以防止对数据架构进行的某些更改或记录数据中的更改或事件操作。
3.登录触发器
登录触发器将为响应 LOGIN 事件而激发存储过程。与 SQL Server 实例建立用户会话时将引发此事件。登录触发器将在登录的身份验证阶段完成之后且用户会话实际建立之前激发。因此,来自触发器内部且通常将到达用户的所有消息(例如错误消息和来自 PRINT 语句的消息)会传送到 SQL Server 错误日志。如果身份验证失败,将不激发登录触发器。
四:触发器的工作原理
触发器触发时:
- 系统自动在内存中创建deleted表或inserted表;
- 只读,不允许修改,触发器执行完成后,自动删除。
inserted表:
- 临时保存了插入或更新后的记录行;
- 可以从inserted表中检查插入的数据是否满足业务需求;
- 如果不满足,则向用户发送报告错误消息,并回滚插入操作。
deleted表:
- 临时保存了删除或更新前的记录行;
- 可以从deleted表中检查被删除的数据是否满足业务需求;
- 如果不满足,则向用户报告错误消息,并回滚插入操作。
inserted表和deleted表对照:
修改操作记录 | inserted表 | deleted表 |
增加(insert)记录 | 存放新增的记录 | ............ |
删除(deleted)记录 | .............. | 存放被删除的记录 |
修改(update)记录 | 存放更新后的记录 | 存放更新前的记录 |
五:创建触发器
创建触发器的语法:
CREATE TRIGGER trigger_nameON table_name[WITH ENCRYPTION]FOR | AFTER | INSTEAD OF [DELETE, INSERT, UPDATE]AS T-SQL语句
GO
--with encryption 表示加密触发器定义的sql文本
--delete,insert,update指定触发器的类型
准备测试数据:
--创建学生表
create table student(stu_id int identity(1,1) primary key,stu_name varchar(10),stu_gender char(2),stu_age int
)
1.创建insert触发器
--创建insert触发器
create trigger trig_insert
on student
after insert
as
beginif object_id(N'student_sum',N'U') is null--判断student_sum表是否存在create table student_sum(stuCount int default(0));--创建存储学生人数的student_sum表declare @stuNumber int;select @stuNumber = count(*)from student;if not exists (select * from student_sum)--判断表中是否有记录insert into student_sum values(0);update student_sum set stuCount =@stuNumber; --把更新后总的学生数插入到student_sum表中
end
--测试触发器trig_insert-->功能是向student插入数据的同时级联插入到student_sum表中,更新stuCount
--因为是后触发器,所以先插入数据后,才触发触发器trig_insert;
insert into student(stu_name,stu_gender,stu_age)values('吕布','男',30);
select stuCount 学生总人数 from student_sum;
insert into student(stu_name,stu_gender,stu_age)values('貂蝉','女',30);
select stuCount 学生总人数 from student_sum;
insert into student(stu_name,stu_gender,stu_age)values('曹阿瞒','男',40);
select stuCount 学生总人数 from student_sum;
执行上面的语句后,结果如下图所示:
既然定义了学生总数表student_sum表是向student表中插入数据后才计算学生总数的,所以学生总数表应该禁止用户向其中插入数据
--创建insert_forbidden,禁止用户向student_sum表中插入数据
create trigger insert_forbidden
on student_sum
after insert
as
beginRAISERROR('禁止直接向该表中插入记录,操作被禁止',1,1)--raiserror 是用于抛出一个错误
rollback transaction
end
--触发触发器insert_forbidden
insert student_sum (stuCount) values(5);
结果如下:
2.创建delete触发器
用户执行delete操作,就会激活delete触发器,从而控制用户能够从数据库中删除数据记录,触发delete触发器后,用户删除的记录会被添加到deleted表中,原来表的相应记录被删除,所以在deleted表中查看删除的记录。
--创建delete触发器
create trigger trig_delete
on student
after delete
as
beginselect stu_id as 已删除的学生编号,stu_name stu_gender,stu_agefrom deleted
end;
--执行一一条delete语句触发trig_delete触发器
delete from student where stu_id=1;
结果如下:
3.创建UPDATE触发器
update触发器是当用户在指定表上执行update语句时被调用被调用,这种类型的触发器用来约束用户对数据的修改。update触发器可以执行两种操作:更新前的记录存储在deleted表中,更新后的记录存储在inserted表中。
--创建update触发器
create trigger trig_update
on student
after update
as
begindeclare @stuCount int;select @stuCount=count(*) from student;update student_sum set stuCount =@stuCount;select stu_id as 更新前学生编号,stu_name as 更新前学生姓名 from deletedselect stu_id as 更新后学生编号,stu_name as 更新后学生姓名 from inserted
end
--创建完成,执行一条update语句触发trig_update触发器
update student set stu_name='张飞' where stu_id=2;
4.创建替代触发器
与前面介绍的三种after触发器不同,SqlServer服务器在执行after触发器的sql代码后,先建立临时的inserted表和deleted表,然后执行代码中对数据库操作,最后才激活触发器中的代码。而对于替代(instead of)触发器,SqlServer服务器在执行触发instead of 触发器的代码时,先建立临时的inserted表和deleted表,然后直接触发instead of触发器,而拒绝执行用户输入的DML操作语句。
--创建instead of 触发器
create trigger trig_insteadOf
on student
instead of insert
as
begindeclare @stuAge int;select @stuAge=(select stu_age from inserted)
if(@stuAge >120)select '插入年龄错误' as '失败原因'
end
创建完成,执行一条insert语句触发触发器trig_insteadOf
5.嵌套触发器介绍
如果一个触发器在执行操作时调用了另外一个触发器,而这个触发器又接着调用了下一个触发器,那么就形成了嵌套触发器。嵌套触发器在安装时就被启用,但是可以使用系统存储过程sp_configure禁用和重新启用嵌套触发器。
嵌套触发器不一定要形成一个环,它可以 T1->T2->T3...这样一直触发下去,最多允许嵌套 32 层。如果嵌套的次数超过限制,那么该触发器将被终止,并回滚整个事务,使用嵌套触发器需要注意以下几点:
- 默认情况下,嵌套触发器配置选项是开启的。
- 在同一个触发器事务中,一个嵌套触发器不能被触发两次。
- 由于触发器是一个事务,如果在一系列嵌套触发器的任意层次中发生错误,则整个事物都将取消,而且所有数据回滚。
嵌套是用来保持整个数据库的完整性的重要功能,但有时可能需要禁用嵌套,如果禁用了嵌套,那么修改一个触发器的实现不会再触发该表上的任何触发器。在下述情况下,需要禁用嵌套触发器:
- 嵌套触发要求复杂而有理论的设计,级联修改可能会修改用户不想涉及的数据。
- 在一系列嵌套触发器中的任意点的时间修改操作都会触发一些触发器,尽管这时数据库提供很强的保护功能,但如果以特定的顺序更新表,就会产生问题。
使用下列语句禁用嵌套和再次启用嵌套:
--禁用嵌套
exce sp_configure 'nested triggers',0;
--启用嵌套
exce sp_configure 'nested triggers',1;
6.递归触发器
触发器的递归是指一个触发器从其内部再一次激活该触发器,例如update操作激活的触发器内部还有一条数据表的更新语句,那么这个更新语句就有可能激活这个触发器本身,当然,这种递归的触发器内部还会有判断语句,只有一定情况下才会执行那个T_SQL语句,否则就成为无线调用的死循环了。
SqlServer中的递归触发器包括两种:直接递归和间接递归。
- 直接递归:触发器被触发后并执行一个操作,而该操作又使用一个触发器再次被触发。
- 间接递归:触发器被触发并执行一个操作,而该操作又使另一个表中的某个触发器被触发,第二个触发器使原始表得到更新,从而再次触发第一个触发器。
默认情况下,递归触发器选项是禁用的。递归触发器最多只能递归16层,如果递归中的第16个触发器激活了第17个触发器,则结果与发布的rollback命令一样,所有数据都将回滚。
我们举例解释如下,假如有表1、表2名称分别为 T1、T2,在 T1、T2 上分别有触发器 G1、G2。
- 间接递归:对 T1 操作从而触发 G1,G1 对 T2 操作从而触发 G2,G2 对 T1 操作从而再次触发 G1...
- 直接递归:对 T1 操作从而触发 G1,G1 对 T1 操作从而再次触发 G1...
设置直接递归:
默认情况下是禁止直接递归的,要设置为允许有两种方法:
- T-SQL:exec sp_dboption 'dbName', 'recursive triggers', true;
- EM:数据库上点右键->属性->选项。
六:管理触发器
1.查看触发器
(1).查看数据库中所有的触发器
--查看数据库中所有的触发器
use 数据库名
go
select * from sysobjects where xtype='TR'
sysobjects 保存着数据库的对象,其中 xtype 为 TR 的记录即为触发器对象。在 name 一列,我们可以看到触发器名称。
(2).sp_helptext 查看触发器内容
use 数据库名
go
exec sp_helptext '触发器名称'
将会以表的样式显示触发器内容。
除了触发器外,sp_helptext 还可以显示 规则、默认值、未加密的存储过程、用户定义函数、视图的文本。
(3).sp_helptrigger 用于查看触发器的属性
sp_helptrigger 有两个参数:第一个参数为表名;第二个为触发器类型,为 char(6) 类型,可以是 INSERT、UPDATE、DELETE,如果省略则显示指定表中所有类型触发器的属性。
use 数据库名
go
exec sp_helptrigger tableName
2.禁用启用触发器
禁用:alter table 表名 disable trigger 触发器名称
启用:alter table 表名 enable trigger 触发器名称
如果有多个触发器,则各个触发器名称之间用英文逗号隔开。
如果把“触发器名称”换成“ALL”,则表示禁用或启用该表的全部触发器。
3修改触发器
--修改触发器语法
ALTER TRIGGER trigger_name ON table_name [ WITH ENCRYPTION ] FOR {[DELETE][,][INSERT][,][UPDATE]}ASsql_statement;
4.删除触发器
--语法格式:DROP TRIGGER { trigger } [ ,...n ]
参数:trigger: 要删除的触发器名称n:表示可以删除多个触发器的占位符
相关文章:

SqlServer基础之(触发器)
概念: 触发器(trigger)是SQL server 提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发&#x…...

数据结构刷题训练:队列实现栈
目录 前言 1. 题目:使用队列实现栈 2. 思路 3. 分析 3.1 创建栈 3.2入栈 3.3 出栈 3.4 栈顶数据 3.5 判空和 “ 栈 ” 的销毁 4. 题解 总结 前言 我们已经学习了栈和队列,也都实现了它们各自的底层接口,那么接下我们就要开始栈和队列的专项刷…...

(统计学习方法|李航)第四章 朴素贝叶斯算法——贝叶斯估计
贝叶斯估计方法: 计算男女时只有两个值,所以K2 贝叶斯估计就是拉普拉斯平滑 估计方法:为什么叫做贝叶斯估计呢? 例题: 重新回顾以下朴素贝叶斯: 对他求导,求出最大值 得到了色i他的估计值&…...

企业直播MR虚拟直播(MR混合现实直播技术)视频介绍
到底什么是企业直播MR虚拟直播(MR混合现实直播技术)? 企业直播MR虚拟直播新玩法(MR混合现实直播技术) 我的文章推荐: [视频图文] 线上研讨会是什么,企业对内对外培训可以用线上研讨会吗&#x…...
React Fiber: 从 Reconciliation 到 Concurrent Mode
React Fiber 是 React 中的一种新的协调算法,它的主要目的是提高 React 的性能和可维护性。在 React Fiber 之前,React 使用了一种叫做 Stack Reconciliation 的算法来处理组件的更新和渲染。但是 Stack Reconciliation 存在一些问题,比如无法…...

【PostgreSQL内核学习(十一)—— OpenGauss源码学习(CopyTo)】
可优化语句执行 概述什么是列存储?列存的优势 相关函数CopyToCStoreCopyToCopyStatetupleDescCStoreScanDesc CStoreBeginScanRelationSnapshotProjectionInfo GetCStoreNextBatchRunScanFillVecBatchCStoreIsEndScan CStoreEndScan 声明:本文的部分内容…...

计算机网络 网络层 IPv4地址
A类地址第一位固定0 B类10 其下同理...
【程序员社交】多和高层次人群交流
定义问题:如何多和高层次人群交流获取经验提升自己? 收集信息:通过社交媒体、行业论坛、行业大会等途径获取高层次人群的信息和观点,并了解他们的工作经历、技能和能力。 分析信息:分析收集到的信息,了解…...
机器学习笔记 - 基于C++的深度学习 三、实现成本函数
机器学习中的建模 作为人工智能工程师,我们通常将每个任务或问题定义为一个函数。 例如,如果我们正在开发面部识别系统,我们的第一步是将问题定义为将输入图像映射到标识符的函数F(X)。但是问题是如何知道F(X)公式? 事实上,使用公式或一系列固有规则来定义F(X)是不可行的(…...

lazada、shopee店铺如何利用测评提高权重和排名?
在 lazada、shopee平台上开店后,卖家们必须对店铺的权重进行更多的关注。如果店铺的权重越高,那么它就会带来更多的流量和更多的订单,那么在 lazada、shopee平台上开设一家店铺,该怎样增加它的店铺权重和排名呢? laza…...

安全第二次
一,iframe <iframe>标签用于在网页里面嵌入其他网页。 1,sandbox属性 如果嵌入的网页是其他网站的页面,因不了解对方会执行什么操作,因此就存在安全风险。为了限制<iframe>的风险,HTML 提供了sandb…...
125、SpringBoot可以同时处理多少请求?
SpringBoot可以同时处理多少请求? 一、前言二、线程池4大参数图解三、代码示例一、前言 我们都知道,SpringBoot默认的内嵌容器是Tomcat,也就是我们的程序实际上是运行在Tomcat里的。所以与其说SpringBoot可以处理多少请求,到不如说Tomcat可以处理多少请求。 关于Tomcat的默…...

SSE技术和WebSocket技术实现即时通讯
文章目录 一、SSE1.1 什么是SSE1.2 工作原理1.3 特点和适用场景1.4 API用法1.5 代码实现 二、WebSocket2.1 什么是WebSocket2.2 工作原理2.3 特点和适用场景2.4 API用法2.5 代码实现2.6 心跳检测 三、SSE与WebSocket的比较 当涉及到实现实时通信的Web应用程序时,两种…...

什么是敏捷开发?
敏捷开发流程:制度化、规范化地PUA程序员的顶级神器!!!...
tcp发送整型,结构体等数据的方法
测试环境 Receiver: x86 UbuntuSender: arm64 android 发送整型数 C语言和套接字库来发送一个整型变量(int)的客户端程序。 它首先创建一个TCP套接字,然后连接到指定的服务器地址和端口。接着,它将一个整型变量(in…...

【Unity每日一记】让一个物体按余弦曲线移动—(三角函数的简单运用)
👨💻个人主页:元宇宙-秩沅 👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 秩沅 原创 👨💻 收录于专栏:uni…...
python爬虫实战——数据可视化
本篇文章将介绍如何利用Python爬虫获取数据并进行可视化展示,包括以下主要内容: 数据获取:使用requests库发送HTTP请求获取目标网页的数据;数据解析:使用BeautifulSoup库对HTML代码进行解析提取所需数据;数…...

案例13 Spring MVC参数传递案例
基于Spring MVC实现HttpServletRequest、基本数据类型、Java Bean、数组、List、Map、JSON方式的参数传递。 1. 创建项目 选择Maven快速构建web项目,项目名称为case13-springmvc02。 2. 配置Maven依赖 <?xml version"1.0" encoding"UTF-8&quo…...

IntellIJ Idea 连接数据库-MySql
前言:可以用mariaDB工具,在本地创建服务器主机和数据库,而后用intellIJ Idea尝试连接 MariaDB创建数据库练习 1.IntellIJ Idea打开界面右侧Database工具,选择MySQL数据库。 2.填写数据库账号密码,地址端口号ÿ…...

通讯协议036——全网独有的OPC HDA知识一之聚合(五)计数
本文简单介绍OPC HDA规范的基本概念,更多通信资源请登录网信智汇(wangxinzhihui.com)。 本节旨在详细说明HDA聚合的要求和性能。其目的是使HDA聚合标准化,以便HDA客户端能够可靠地预测聚合计算的结果并理解其含义。如果用户需要聚合中的自定义功能&…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

CTF show 数学不及格
拿到题目先查一下壳,看一下信息 发现是一个ELF文件,64位的 用IDA Pro 64 打开这个文件 然后点击F5进行伪代码转换 可以看到有五个if判断,第一个argc ! 5这个判断并没有起太大作用,主要是下面四个if判断 根据题目…...

可视化预警系统:如何实现生产风险的实时监控?
在生产环境中,风险无处不在,而传统的监控方式往往只能事后补救,难以做到提前预警。但如今,可视化预警系统正在改变这一切!它能够实时收集和分析生产数据,通过直观的图表和警报,让管理者第一时间…...

Linux【5】-----编译和烧写Linux系统镜像(RK3568)
参考:讯为 1、文件系统 不同的文件系统组成了:debian、ubuntu、buildroot、qt等系统 每个文件系统的uboot和kernel是一样的 2、源码目录介绍 目录 3、正式编译 编译脚本build.sh 帮助内容如下: Available options: uboot …...
Flask和Django,你怎么选?
Flask 和 Django 是 Python 两大最流行的 Web 框架,但它们的设计哲学、目标和适用场景有显著区别。以下是详细的对比: 核心区别:哲学与定位 Django: 定位: "全栈式" Web 框架。奉行"开箱即用"的理念。 哲学: "包含…...
n8n:解锁自动化工作流的无限可能
在当今快节奏的数字时代,无论是企业还是个人,都渴望提高工作效率,减少重复性任务的繁琐操作。而 n8n,这个强大的开源自动化工具,就像一位智能的数字助手,悄然走进了许多人的工作和生活,成为提升…...