我的编程空间,编程开发者的网络收藏夹
学习永远不晚

SQL Server的触发器详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

SQL Server的触发器详解

一、概念

触发器是一种特殊类型的存储过程,不由用户直接调用。

创建触发器时会对其进行定义,以便在对特定表或列作特定类型的数据修改时执行。

触发器可以查询其他表,而且可以包含复杂的SQL语句。 它们主要用于强制服从复杂的业务规则或要求。 例如,您可以根据客户当前的帐户状态,控制是否允许插入新订单。

触发器也可用于强制引用完整性,以便在多个表中添加、更新或删除行时,保留在这些表之间所定义的关系。

二、使用触发器优缺点

  • 触发器可通过数据库中的相关表实现级联更改;通过级联引用完整性约束可以更有效地执行这些更改。
  • 触发器可以强制比用 CHECK 约束定义的约束更为复杂的约束。与 CHECK 约束不同,触发器可以引用其它表中的列。例如,触发器可以使用另一个表中的 SELECT 比较插入或更新的数据,以及执行其它操作,如修改数据或显示用户定义错误信息。
  • 触发器还可以强制执行业务规则
  • 触发器也可以评估数据修改前后的表状态,并根据其差异采取对策。

尽管触发器有很多优点,但是在实际的项目开发中,特别是OOP思想的深入,触发器的弊端也逐渐突显,主要:

  • 过多的触发器使得数据逻辑变得复杂
  • 数据操作比较隐含,不易进行调整修改
  • 触发器的功能逐渐在代码逻辑或事务中替代实现,更符合OO思想。

使用触发器需慎重。

三、语法

CREATE TRIGGER trigger_name 
ON {table_name | view_name} 
{FOR | After | Instead of } [ insert, update,delete ]
AS           
    sql_statement

四、触发器类型

SQL Server 包括两种常规类型的触发器:数据操作语言 (DML) 触发器和数据定义语言 (DDL) 触发器。

当INSERT、UPDATE 或 DELETE 语句修改指定表或视图中的数据时,可以使用 DML 触发器。

DDL 触发器激发存储过程以响应各种 DDL 语句,这些语句主要以CREATE、ALTER 和 DROP 开头。 DDL 触发器可用于管理任务,例如审核和控制数据库操作。

1、数据操作语言 (DML) 触发器

通常说的触发器就是DML触发器。

DML 触发器在 INSERT、UPDATE 和 DELETE 语句上操作,并且有助于在表或视图中修改数据时强制业务规则,扩展数据完整性。

DML触发器又分以下分类:

1、After触发器

After触发器要求只有执行某一操作insert、update、delete之后触发器才被触发,且只能定义在表上。

  • insert触发器
  • update触发器
  • delete触发器

2、Instead of 触发器

Instead of 触发器表示并不执行其定义的操作(insert、update、delete)而仅是执行触发器本身。既可以在表上定义instead of触发器,也可以在视图上定义。

2、数据定义语言 (DDL) 触发器

在SQL Server2005后又增加了DDL触发器。

DDL 触发器将激发存储过程以响应事件。但与 DML 触发器不同的是,它们不会为响应针对表或视图的 UPDATE、INSERT 或 DELETE 语句而激发。相反,它们将为了响应各种数据定义语言 (DDL) 事件而激发。这些事件主要与以关键字 CREATE、ALTER 和 DROP 开头的 Transact-SQL 语句对应。执行 DDL 式操作的系统存储过程也可以激发 DDL 触发器。

DDL 触发器使用场合:

  • 要防止对数据库架构进行某些更改。
  • 希望数据库中发生某种情况以响应数据库架构中的更改。
  • 要记录数据库架构中的更改或事件。

五、DML触发器具体应用

在触发器实际应用中,主要还是建立约束以及级联更新。

inserted与deleted表

触发器有两个特殊的表:插入表(instered表)和删除表(deleted表)。这两张是逻辑表也是虚表。有系统在内存中创建者两张表,不会存储在数据库中。而且两张表的都是只读的,只能读取数据而不能修改数据。

这两张表的结果总是与被改触发器应用的表的结构相同。当触发器完成工作后,这两张表就会被删除。Inserted表的数据是插入或是修改后的数据,而deleted表的数据是更新前的或是删除的数据。

1、insert触发器

原理:当触发INSERT触发器时,新的数据行就会被插入到触发器表和inserted表中。inserted表是一个逻辑表,它包含了已经插入的数据行的一个副本。inserted表包含了INSERT语句中已记录的插入动作。inserted表还允许引用由初始化INSERT语句而产生的日志数据。触发器通过检查inserted表来确定是否执行触发器动作或如何执行它。inserted表中的行总是触发器表中一行或多行的副本。

场景:增加学生信息时,要校验其年龄,暂定其年龄必须大于18,否则新增失败

作用:校验约束

--触发器新增:只允许录取18岁以上学生
IF OBJECT_ID (N'TRIGER_Students_Insert', N'tr') IS NOT NULL
    DROP TRIGGER TRIGER_Students_Insert;
GO

CREATE TRIGGER TRIGER_Students_Insert
ON Students
FOR INSERT
AS
    declare @age int
    select @age=COUNT(Students.ID) FROM Students INNER JOIN inserted ON Students.ID =inserted.ID    
    PRINT @age
    if(@age<18)
    begin
        raiserror('学生年龄必须要大于18哦',16,8)
        rollback tran
    end

2、update触发器

原理:可将UPDATE语句看成两步操作:即捕获数据前像(before image)的DELETE语句,和捕获数据后像(after image)的INSERT语句。当在定义有触发器的表上执行UPDATE语句时,原始行(前像)被移入到deleted表,更新行(后像)被移入到inserted表。

触发器检查deleted表和inserted表以及被更新的表,来确定是否更新了多行以及如何执行触发器动作。

可以使用IF UPDATE语句定义一个监视指定列的数据更新的触发器。这样,就可以让触发器容易的隔离出特定列的活动。当它检测到指定列已经更新时,触发器就会进一步执行适当的动作,例如发出错误信息指出该列不能更新,或者根据新的更新的列值执行一系列的动作语句。

场景:专业信息ID修改,对应的学生信息中专业ID也相应进行修改

--更新触发器:更新专业ID时,同时更新学生的专业信息
IF OBJECT_ID (N'TRIGER_Majors_Update', N'tr') IS NOT NULL
    DROP TRIGGER TRIGER_Majors_Update;
GO

CREATE TRIGGER TRIGER_Majors_Update
ON Majors
FOR UPDATE
AS
    IF UPDATE(ID)
    UPDATE Students Set MajorID=inserted.ID
    FROM Students,deleted,inserted
    WHERE Students.MajorID = deleted.ID

3、delete触发器

原理:当触发DELETE触发器后,从受影响的表中删除的行将被放置到一个特殊的deleted表中。deleted表是一个逻辑表,它保留已被删除数据行的一个副本。deleted表还允许引用由初始化DELETE语句产生的日志数据。

使用DELETE触发器时,需要考虑以下的事项和原则:

  • 当某行被添加到deleted表中时,它就不再存在于数据库表中;因此,deleted表和数据库表没有相同的行。
  • 创建deleted表时,空间是从内存中分配的。deleted表总是被存储在高速缓存中。
  • 为DELETE动作定义的触发器并不执行TRUNCATE TABLE语句,原因在于日志不记录TRUNCATE TABLE语句。

场景:学校某选修课取消。

处理逻辑:在删除课程的同时,需要删除该课程的选课信息。

--删除触发器:删除课程时,同时删除该课程的选课信息
IF OBJECT_ID (N'TRIGER_Courses_Delete', N'tr') IS NOT NULL
    DROP TRIGGER TRIGER_Courses_Delete;
GO

CREATE TRIGGER TRIGER_Courses_Delete
ON Courses
FOR DELETE
AS
    DELETE SC
    FROM SC,deleted     
    WHERE SC.CourseID = deleted.ID

4、Instead Of 触发器

用Instead Of触发器实现与实例3相同的功能,具体实现代码如下:

--Instead Of触发器:删除课程时,同时删除该课程的选课信息
IF OBJECT_ID (N'TRIGER_Courses_Instead_Delete', N'tr') IS NOT NULL
    DROP TRIGGER TRIGER_Courses_Instead_Delete;
GO

CREATE TRIGGER TRIGER_Courses_Instead_Delete
ON Courses
Instead Of DELETE
AS
    declare @courseId int
    --获取要删除的课程ID
    SELECT @courseId=ID FROM deleted
    --删除选课信息
    DELETE FROM SC WHERE CourseID = @courseId
    --删除课程信息
    DELETE FROM Courses WHERE ID=@courseId

六、触发器相关操作

1、删除触发器

drop trigger 触发器名称

删除多个触发器:drop trigger 触发器名称,触发器名称

2、重命名触发器

用查询分析器重命名或

exec sp_rename 原名称, 新名称

sp_rename 是 SQL Server自带的一个存储过程,用于更改当前数据库中用户创建的对象的名称,如表名、列表、索引名等。

3、查看数据库中所有的触发器

select * from sysobjects where xtype='TR'

sysobjects 保存着数据库的对象,其中 xtype 为 TR 的记录即为触发器对象。在 name 一列,我们可以看到触发器名称。

4、sphelptext 查看触发器内容

exec sp_helptext '触发器名称'

5、sp_helptrigger 用于查看触发器的属性

sp_helptrigger 有两个参数:第一个参数为表名;第二个为触发器类型,为 char(6) 类型,可以是 INSERT、UPDATE、DELETE,如果省略则显示指定表中所有类型触发器的属性。

exec sp_helptrigger tbl

七、递归、嵌套触发器

1、递归触发器

递归分两种,间接递归和直接递归。我们举例解释如下,假如有表1、表2名称分别为 T1、T2,在 T1、T2 上分别有触发器 G1、G2。

  • 间接递归:对 T1 操作从而触发 G1,G1 对 T2 操作从而触发 G2,G2 对 T1 操作从而再次触发 G1...
  • 直接递归:对 T1 操作从而触发 G1,G1 对 T1 操作从而再次触发 G1...

2、嵌套触发器

类似于间接递归,间接递归必然要形成一个环,而嵌套触发器不一定要形成一个环,它可以 T1->T2->T3...这样一直触发下去,最多允许嵌套 32 层。

3、设置直接递归

默认情况下是禁止直接递归的,要设置为允许有两种方法:

exec sp_dboption 'dbName', 'recursive triggers', true

也可以EM:数据库上点右键->属性->选项。

4、设置间接递归、嵌套

默认情况下是允许间接递归、嵌套的,要设置为禁止有两种方法:

exec sp_configure 'nested triggers', 0 --第二个参数为 1 则为允许

也可以EM:注册上点右键->属性->服务器设置。

八、触发器回滚

我们看到许多注册系统在注册后都不能更改用户名,但这多半是由应用程序决定的, 如果直接打开数据库表进行更改,同样可以更改其用户名,在触发器中利用回滚就可以巧妙地实现无法更改用户名。

create trigger tr
on 表名
for update
as
    if update(userName)
        rollback tran

关键在最后两句,其解释为:如果更新了 userName 列,就回滚事务。

九、禁用、启用触发器

禁用:

alter table 表名 disable trigger 触发器名称

启用:

alter table 表名 enable trigger 触发器名称

如果有多个触发器,则各个触发器名称之间用英文逗号隔开。

如果把“触发器名称”换成“ALL”,则表示禁用或启用该表的全部触发器。

到此这篇关于SQL Server触发器的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

SQL Server的触发器详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

SQL SERVER触发器详解

SQL Server触发器是一种特殊的存储过程,它是与表相关联的,当表中插入、更新或删除数据时,触发器会自动执行。触发器可以用于强制实施业务规则、自动更新相关数据、记录数据变更等操作。触发器有两种类型:AFTER触发器和INSTEAD OF
2023-08-17

SQL Server的触发器怎么创建

这篇文章主要讲解了“SQL Server的触发器怎么创建”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SQL Server的触发器怎么创建”吧!触发器是一种特殊类型的存储过程,它不同于之前的
2023-06-29

SQL SERVER触发器怎么使用

SQL Server触发器可以在数据库中的表上定义,当满足特定条件时,触发器会自动执行一些操作。以下是使用SQL Server触发器的一般步骤:1. 创建触发器:使用CREATE TRIGGER语句创建触发器,指定触发器的名称、触发时机(例
2023-08-18

SQL SERVER触发器怎么创建

本篇内容主要讲解“SQL SERVER触发器怎么创建”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SQL SERVER触发器怎么创建”吧!触发器是一种特殊的存储过程,触发器主要是通过事件进行触发
2023-06-29
2024-04-02

sql触发器的三种触发方式

sql 触发器的触发方式有:before:在数据修改前触发,用于强制业务规则。after insert:在插入新行后触发,用于向其他表添加或更新数据。after update:在更新现有行后触发,用于更新相关表或记录更改历史。SQL 触发器
sql触发器的三种触发方式
2024-04-13

Oracle触发器详解

Oracle触发器是一种数据库对象,它可以在特定的数据操作(如插入、更新或删除)发生时自动执行一段预定义的PL/SQL代码。触发器可以用于实现复杂的业务逻辑,数据约束和数据一致性的维护等功能。Oracle触发器可以在表级别或行级别上定义,
Oracle触发器详解
2024-04-09

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录