发布时间:2025-12-09 16:48:21 浏览次数:4
什么是触发器
触发器是一种特殊的存储过程。但触发器没有输入和输出参数,因而不能被显示调用。它作为语句的执行结果自动引发,而存储过程则是通过存储过程名称被直接调用。
触发器的功能
1. 强化约束
2. 跟踪变化
3. 级联运行
4. 调用存储过程
触发器种类
常用 DML触发器,DDL触发器用的相对来说比较少。
DML触发器:
用户通过数据操作语句 DML(对表或视图的insert、delete、update)编辑数据,则执行DML触发器。系统将触发器和触发它的语句作为可在触发器内回滚的单个事务对待。如果检测到错误,则整个事务自动回滚。
DDL触发器
为了响应各种数据定义语言 DDL(以CREATE、INSTERT、UPDATE)事件而激发。可以用于在数据库执行管理任务。
触发器分类
一个表可以创建多个 After触发器,但只能创建一个 instead of触发器
after
这类触发器是在记录已经被修改完,事务已提交后被触发执行。主要用记录变更后的处理或检查,一旦发现BUG,可以使用ROLLBACK TRANSACTION语句回滚本次操作。
instead of
这类触发器不去执行其定义的操作(Insert、update、delete),交给触发器执行,触发器检查操作是否正确,若正确则执行操作。这类触发器用来取代原本的操作,在记录变更之前被触发。
触发器中的逻辑(虚拟)表
当表修改时,无论增加、修改、删除,在数据行中的操作,会保存在 inserted--插入表 和 delete--删除表 两个逻辑表中。
| insert | 是 | 否 |
| update | 修改之后的数据 | 修改之前的数据 |
| delete | 否 | 是 |
创建 DML触发器 T-SQL语句
CREATE TRIGGER 触发器名称ON { table | view }{ FOR | AFTER | INSTEAD OF }{ [INSERT] | [UPDATE] | [DELETE] }ASSQL语句[,...n]要求:修改student 表数据,修改之后查询修改后的数据。
创建触发器SQL语句
--创建修改之后的触发器CREATE TRIGGER trig_student_AfterON studentFOR UPDATE AS PRINT 'THE TRIGGER IS AFTER'SELECT * FROM student触发器被触发的SQL语句
update student set ssex='女' where s_id='20070102'执行结果
要求:插入数据前判断 s_id 是否已经存在,若存在则输出 ‘插入ID已经存在,不允许插入’ +插入学生的学号,并进行回滚数据;反之,进行插入操作,并输出’成功执行’+插入学生的学号。
创建触发器SQL语句
--创建修改之后的触发器CREATE TRIGGER trig_student_InsteadOFON studentInstead OF INSERT AS PRINT 'THE TRIGGER IS instead of'declare @id char(10)select @id=s_id from inserted--判断新插入的数据是否存在IF EXISTS(SELECT s_id FROM student where s_id=@id)BEGINROLLBACK TRANSACTIONPRINT '插入ID已经存在,不允许插入'+@idENDELSEBEGININSERT INTO student SELECT * FROM insertedPRINT '成功执行'+@idEND触发器被触发的SQL语句
INSERT INTO student ([s_id],[sname],[ssex],[sbirthday],[sdepartment],[smajor],[spoliticalStatus],[photo],[smemo])VALUES('20070104',N'张莉',N'女','1/30/1998',N'信息工程学院',N'计算机',N'党员',NULL,NULL)执行结果 – 数据库未存在 学生的学号
执行结果 – 数据库已存在 学生的学号
要求:插入数据库后输入 ‘创建数据库’
CREATE TRIGGER trig_createON ALL SERVERAFTER CREATE_DATABASEASPRINT '创建数据库'触发器被触发的SQL语句
IF EXISTS(SELECT * FROM sysdatabases WHERE name='StuInfo1')PRINT 'StuInfo1数据库已存在'ELSEBEGIN--创建数据库CREATE DATABASE StuInfo1ON(NAME=StuInfo1,FILENAME='D:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA\StuInfo1.mdf',SIZE=3MB,MAXSIZE=UNLIMITED,FILEGROWTH=10%)LOG ON(NAME=StuInfo1_log,FILENAME='D:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA\StuInfo1_log.ldf',SIZE=1MB,MAXSIZE=100MB,FILEGROWTH=10%)END执行结果
修改 DML触发器 T-SQL 语句 :可以将创建 DML触发器的关键字 CREATE 修改为 ALTER,这里不再举例子。
修改 DDL触发器 T-SQL 语句 :可以将创建 DDL 触发器的关键字 CREATE 修改为 ALTER,这里不再举例子。
举例 :删除trig_student_After触发器
DROP TRIGGER trig_student_After执行结果
创建触发器举例用的数据
可以将下方SQL语句 复制到 SSMS 工具上直接执行,如果有时间,建议自己敲一遍。扩展一点,SQL语句关键字最好使用大写。如果使用小写,数据库会将关键字从小写转换为大写,增加这一过程则性能会降低,所以最好直接使用大写。
use mastergo-- 判断数据库是否已经存在,若存在不删除直接使用,反之新建IF EXISTS(SELECT * FROM sysdatabases WHERE name='StuInfo')PRINT 'StuInfo数据库已存在'ELSEBEGIN--创建数据库CREATE DATABASE StuInfoON(NAME=StuInfo,FILENAME='D:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA\StuInfo.mdf',SIZE=3MB,MAXSIZE=UNLIMITED,FILEGROWTH=10%)LOG ON(NAME=StuInfo_log,FILENAME='D:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA\StuInfo_log.ldf',SIZE=1MB,MAXSIZE=100MB,FILEGROWTH=10%)ENDGOUSE StuInfoGO-- 判断数据表是否已经存在,若存在删除后创建IF OBJECT_ID(N'StuInfo..student',N'U') IS NOT NULLDROP TABLE studentCREATE TABLE student([s_id][char](10)NOT NULL,[sname][nvarchar](5)NULL,[ssex][nvarchar](1)NULL,[sbirthday][date]NULL,[sdepartment][nvarchar](10)NULL,[smajor][nvarchar](10)NULL,[spoliticalStatus][nvarchar](4)NULL,[phoneName][varchar](100)NULL,[photo][varchar](max)NULL,[smemo][nvarchar](max)NULL,CONSTRAINT[PK_student]PRIMARY KEY CLUSTERED([s_id] ASC))on [PRIMARY]GO-- 向数据库添加数据USE StuInfoINSERT INTO student ([s_id],[sname],[ssex],[sbirthday],[sdepartment],[smajor],[spoliticalStatus],[photo],[smemo])VALUES('20070101',N'张莉',N'女','1/30/1998',N'信息工程学院',N'计算机',N'党员',NULL,NULL),('20070102',N'张建',N'男','1/30/1998',N'信息工程学院',N'计算机',N'党员',NULL,NULL)GO