sqlserver触发器

article/2025/10/13 10:48:58

 为了更好的强制业务规则和保证数据的完整性,sql server为我们提供了两种机制,它们分别是约束(主键约束、外键约束、Not Null约束、唯一约束以及检查约束)和触发器。在触发器中,我们可以查询其他表,也可以包含复杂的Transact-SQL语句,并且可以将触发器和触发它的语句作为可在触发器内回滚的单个事务对待。如果检测到严重错误(例如,磁盘空间不足),则整个事务即自动回滚
  说到这里,我想到了数据库中的另外一个东西——存储过程,它们两个真的是太像了,几乎可以说存储过程可以做什么触发器就可以做什么,所以我们也可以把触发器称作是一种特殊的存储过程,那么,既然它是特殊的存储过程,那它到底特殊在哪里呢?触发器与存储过程最大的不同就是:它是与表事件(insert、delete、update)相关的存储过程,它的执行既不是由程序调用的,也不是由手工调用的,而是由事件来触发的,这就是它的神奇之处,比如当我们对一个表进行操作(insert、delete、update)时就会激活它执行,这就满足了普通存储过程所做不到的一些需求.
触发器与存储过程的区别是运行方式的不同,触发器不能执行EXECUTE语句调用,而是在用户执行Transact-SQL语句时自动触发执行而存储过程需要用户,应用程序或者触发器来显示地调用并执行
一:触发器的优点
 1.触发器是自动的。当对表中的数据做了任何修改之后立即被激活。
 2.触发器可以通过数据库中的相关表进行层叠修改。
 3.触发器可以强制限制。这些限制比用CHECK约束所定义的更复杂。与CHECK约束不同的是,触发器可以引用其他表中的列。
二:触发器的作用
 触发器的主要作用就是其能够实现由主键和外键所不能保证的复杂参照完整性和数据的一致性,它能够对数据库中的相关表进行级联修改,提高比CHECK约束更复杂的的数据完整性,并自定义错误消息。触发器的主要作用主要有以下接个方面:
强制数据库间的引用完整性
级联修改数据库中所有相关的表,自动触发其它与之相关的操作
跟踪变化,撤销或回滚违法操作,防止非法修改数据
返回自定义的错误消息,约束无法返回信息,而触发器可以
触发器可以调用更多的存储过程

触发器的分类
  sql server包括三种常规类型的触发器:DML数据操纵语言(Data Manipulation Language, DML)触发器、DDL 数据库模式定义语言DDL(Data Definition Language)触发器和登录触发器

(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错误日志。如果身份验证失败,将不再激发登录触发器。

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

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

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


--测试数据,首先我们创建测试数据,共有两张表:课程表(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
--创建触发器的语法如下:
CREATE TRIGGER [触发器名称] ON [表名称]FOR UPDATE -- 或DELETE、或INSERT
AS --Transact-SQL(业务逻辑代码)
-- 创建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--当学生表(student)中没有学生学习某一门课程的时候,我们将这门课程自动删除。这时,我们就需要
--创建一个delete触发器,代码如下:
--当学生表(student)中没有学生学习某一门课程的时候,我们将这门课程自动删除。这时,我们就需要
--创建一个delete触发器,代码如下:
delete student where student_id = 'S001'
--现在我们对此触发器做一个测试,我们从上面的测试数据知道,Lucy和Jameson都学习了语文这门课程
--(course_id为“C001”),现在Lucy由于转班去了别的班级,我们需要将此学生的信息删除
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
--给student表中添加任课教师列(course_teacherName)
--然后为在表中的数据添加相关任课教师的名称
-- 创建studnet表的触发器
CREATE TRIGGER [dbo].[course_update] ON [dbo].[course]
FOR UPDATE
AS
IF (UPDATE(course_teacherName))
BEGINraiserror('任课老师不允许修改!',16,1);----raiserror 是用于抛出一个错误rollback tran;
END
--课程的任课教师不允许修改,那么我们就需要创建一个对应的update触发器--创建好了之后,我们再来更新任课教师的内容,这个触发器满足了我们的需求 测试代码如下
UPDATE course SET course_teacherName = '许褚' WHERE course_id = 'C002'

 insert触发器示例

--insert触发器示例
--需求,我们需要在course表中添加更新时间字段(update_time),当我们插入学生的时候,就要对相应的该---课程的时间进行更新,代码如下:
-- 为course表添加字段
ALTER TABLE course
ADD update_time varchar(50)
GO
-- 创建student表的触发器
CREATE TRIGGER [dbo].[course_insert] ON [dbo].[student]
FOR insert
AS
DECLARE @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 '相应课程的修改时间已更新'
--修改触发器语法
ALTER TRIGGER [触发器名称] ON [表名称]FOR UPDATE -- 或DELETE、或INSERT
AS --Transact-SQL(业务逻辑代码)--删除触发器语法
drop trigger 触发器名称
--测试一下,为student表中新添加一个学生
INSERT INTO student VALUES ('S004','张三','C003')

其他示例:

USE [PlatformBase]
GO
/****** Object:  Trigger [dbo].[hairpin]    Script Date: 2022/8/11 14:17:27 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		<Author,,Name>
-- Create date: <Create Date,,>
-- Description:	<Description,,>
-- =============================================
ALTER TRIGGER [dbo].[hairpin]ON   [dbo].[MESGroupProject]AFTER INSERT
AS 
BEGIN-- SET NOCOUNT ON added to prevent extra result sets from-- interfering with SELECT statements. Declare @name1 nvarchar(500);Declare @name2 nvarchar(500);Declare @id varchar(100);select @name1=TodayContent ,@name2 =TomorrowPlan,@id=ID from inserted;if(CHARINDEX('hairpin',LOWER(@name1))>0 or CHARINDEX('hairpin',LOWER(@name2))>0)Begin if exists (select 1 from MESGroupProject where ID=@id)Begindelete from MESGroupProject where ID=@idendinsert  dbo.MESGroupProject([ID],[Del_Sign] ,ProjectNo,[TodayContent] ,[TodayAttach],[TomorrowPlan] ,[TodayProgress],[Add_User] ,[Add_Date] ,[TimeSpan] ,[MESProjectNo],[GroupID] ,[ProjectDate] ,[IsUpload] ,[Log],[UserCode] , [Dep_Project_No]) 
select [ID],[Del_Sign] ,ProjectNo,REPLACE(LOWER(@name1), 'hairpin',' 项目') ,[TodayAttach],REPLACE(LOWER(@name1), 'hairpin',' 项目'),[TodayProgress],[Add_User] ,[Add_Date] ,[TimeSpan] ,[MESProjectNo],[GroupID] ,[ProjectDate] ,[IsUpload] ,[Log],[UserCode] ,[Dep_Project_No] from insertedendSET NOCOUNT ON;-- Insert statements for trigger here
END


http://chatgpt.dhexx.cn/article/F9Da02Ik.shtml

相关文章

SQLServer 触发器

今天修复K3系统生产出库单&#xff0c;审核、返审核 领料数量一直不变&#xff0c;没有相应改变&#xff0c;K3是16年买的&#xff0c;没有源码开发文档和表结构&#xff0c;只能在sqlserver中添加sql语句监视,看审核后改变那个表的状态和数据源sql语句&#xff0c;用触发器改变…

Mac 解压rar 文件

Mac 解压rar 文件 第一种方法&#xff1a; 下载下面链接中的软件&#xff0c;安装好就可以直接用了。 http://baijiahao.baidu.com/s?id1604390455412644388&wfrspider&forpc 安装过程中&#xff0c;一直点击下一步即可 第二种方法&#xff1a; https://blog.csd…

Mac电脑上视频压缩处理

第一步&#xff1a;用QuickTime Player打开你准备压缩的视频 第二步&#xff1a;选择文件——导出——1080P 720P 480P&#xff08;建议用720和480&#xff09; 第三步&#xff1a;选择你想要导出的大小&#xff0c;点击保存 最后一步&#xff0c;等存储完成就了 上面的图片视…

苹果电脑的压缩工具——FastZip

1.FastZip,一键快捷&#xff01; FastZip可以进行分卷压缩解压&#xff0c;支持7Z&#xff0c;ZIP&#xff0c;RAR&#xff0c;TAR&#xff0c;GZIP&#xff0c;BZIP2&#xff0c;XZ&#xff0c;LZIP&#xff0c;ACE&#xff0c;ISO&#xff0c;CAB&#xff0c;PAX&#xff0c…

Linux/macOS的打包、压缩、解压缩

打包 tar&#xff0c;打包后的扩展名为 .tar xxx.tar为打包后的文件名&#xff0c;xxx为被打包的文件 tar -cf xxx.tar xxx压缩 压缩命令为&#xff1a;gzip、bzip2&#xff0c;但是tar命令中已经集成压缩命令&#xff0c;可以通过制定参数进行文件压缩 tar -zcf xxx.tar.…

【Mac-rar文件解压】Mac系统如何打开rar压缩包文件_无需下载应用程序的快捷4步操作法

一位不喜欢下很多应用程序在&#x1f4bb;的目录 0.查阅说明1. 打开终端2.输入命令3. 输入命令4. 开始解压&#xff01; 0.查阅说明 大家好&#x1f44b;&#xff0c;因为本人属实很不喜欢下载很多应用程序在电脑上&#xff0c;因此在网络上找到了另外一种解决解压rar压缩包的…

mac压缩文件多了__MACOSX目录问题

文章目录 背景原因解决方案&#xff1a;更换压缩方式分析问题拓展&#xff08;.DS_Store&#xff09; 背景 项目中有一个场景&#xff0c;需要把目录压缩为app离线包的zip 但是压缩之后一致打不开&#xff0c;别人上传的zip是好的 原因 如图&#xff0c;我上传的在安卓设备…

Mac 终端解压缩命令大全

Mac 终端解压缩命令大全 .zip 解压缩&#xff1a; unzip FileName.zip 压缩&#xff1a; zip FileName.zip DirName zip 使用细节 zip -q -r -e -m -o FileName.zip DirName -q 表示不显示压缩进度状态-r 表示子目录子文件全部压缩为zip //这部比较重要&#xff0c;不然的…

Mac使用命令行工具解压和压缩rar文件

目前在Mac电脑里支持解压缩的格式主要有&#xff1a;zip、gz等&#xff0c;但是还不支持rar格式的文件&#xff0c;接下来带着大家学习一下如何解压缩rar格式文件。 1.下载rar工具 打开&#xff1a;https://www.rarlab.com/download.htm 根据自己电脑的芯片要求选择自己的安装…

如何在Mac上快速压缩和解压文件?Mac上解压和压缩文件的方法

苹果mac电脑怎么压缩和解压文件?Mac电脑仅默认支持把文件压缩成zip格式,解压成zip、tar.gz,bz2等格式,有些操作需要安装第三方软件来完成,这篇文章为大家带来几种关于在Mac上解压和压缩文件的方法,有兴趣的朋友可以来了解一下载哦! 一、解压工具 1.MacOS自带的解压 只能…

Mac有哪些解压缩软件,他们的优缺点是什么,哪款比较好用?

Mac有哪些解压缩软件&#xff0c;他们的优缺点是什么&#xff0c;哪款比较好用&#xff1f; 相信有很多小伙伴和我有一样的疑问&#xff0c;Mac 有哪些解压缩软件&#xff0c;那款更好用哪&#xff1f;下面我们就带着疑问来详细了解一下 Mac 上的常见解压缩软件 一、macZip ⇲…

使用数字芯片将5V转3.3V方案电路图

5V转3.3V常用方案 ## &#xff11;&#xff0e;AMS117 优点&#xff1a;便宜&#xff0c;1毛一片 缺点&#xff1a;体积大 电路图&#xff08;来自正点原子&#xff09;&#xff1a; 2. HT7833 优点&#xff1a;体积比AMS1117小一号 缺点:比1117贵一点&#xff0c;8~9毛…

数字芯片后端设计——SRAM宏模块布局布线

在40nm SMIC工艺下&#xff0c;根据手册总结单端SRAM的布局布线问题。 ArtiGrid power structure options&#xff1a;以下图为例&#xff0c;memory的电源布线&#xff0c;无论是core核还是外围periphery&#xff0c;都是在M4层展开&#xff0c;在整个SRAM宏模块中&#xff0…

华为2019数字芯片岗笔试解析二(单选第三部分)

首发来自公众号&#xff1a;数字芯片设计 21.数字电路设计中&#xff0c;下列哪种手段无法消除竞争冒险现象&#xff08;&#xff09;【A】加滤波电容&#xff0c;消除毛刺【B】增加冗余项消除逻辑冒险【C】增加选通信号&#xff0c;避开毛刺【D】降低时钟频率 解析&#xff1a…

【开卷】第一期(下) ​海思提前批数字芯片笔试(带解析)

2022届的IC招聘&#xff0c;也来的太早了一些。应届生们刚刚办理完入职&#xff0c;各个企业的提前批招聘就突然启动。颇有秋招变夏招的架势。伴随着更多的非科班同学的转行&#xff0c;卷起来已成必然。而各个企业涉猎广泛的笔试题更是打了刚刚开始进行秋招准备的同学们一个措…

华为2019数字芯片岗笔试解析(多选部分)

首发来自微信公众号&#xff1a;数字芯片设计 不定项选择 1.关于状态机编码&#xff0c;如下描述中正确的是&#xff08;&#xff09;【A】状态编码用parameter定义【B】状态机必须有default态【C】用组合逻辑和时序逻辑分离的风格描述FSM【D】用case语句描述状态的转移 解析&a…

华为海思 2021数字芯片/IC 笔试题+解析

题目来源于众多网友对笔试的记录、回忆。 理解不到位&#xff0c;难免出错&#xff0c;解析仅为个人看法&#xff0c;有不同意见请留言指教&#xff0c;谢谢&#xff01; 题型&#xff1a; 30个单选10个多选 单选 1.影响芯片成本的主要因素是die size和封装&#xff0c;但电…

紫光展锐2021数字芯片笔试

紫光展锐2021数字芯片笔试题 一、单选题 A,计算过程参考CRC计算原理介绍B,删除命令的常用用法:rm -rf ./file.txt,mkdir是新建文件夹(目录),mv是移动文件(重命名) 不知道,感觉选A;A,PMOS是形成空穴沟道,衬底需要接VDD B,for…join_none内部各子语句是并行执行;…

告诉你什么是数字芯片和模拟芯片

我们常说隔行如隔山&#xff0c;哪怕你从各种渠道了解到了芯片&#xff0c;可对于芯片你真的了解吗&#xff1f;下面告诉你什么是数字芯片和模拟芯片&#xff1f; 根据芯片的功能不同&#xff0c;划分为两大类数字芯片和模拟芯片。像海思的麒麟系列芯片就是数字芯片里的一种&am…