什么是数据库触发器?

article/2025/10/24 6:43:19

目录

什么是数据库触发器?

事件

AFTER触发器

INSTEAD OF触发器

特殊数据库对象

定义

用于触发器

复杂的审计

执行业务规则

派生列值

触发器很棘手!


什么是数据库触发器?

数据库触发器是在数据库中发生特定操作时运行的特殊存储过程。大多数触发器定义为在对表的数据进行更改时运行。触发器可以定义为替代或在DML(数据操纵语言)-INSERT, UPDATE, and DELETE-之后来运行。

触发器可帮助数据库设计人员确保完成某些操作(如维护审计文件),而不管哪个程序或用户对数据进行了更改。

程序被称为触发器,因为事件(例如向表中添加记录)会触发它们的执行。

触发器及其实现特定于数据库供应商。在本文中,我们将重点介绍Microsoft SQL服务器;但是,OracleMySQL中的概念相同或相似。

注意:本课程的所有示例均基于Microsoft SQL Server Management StudioAdventureWorks2012数据库。

事件

触发器可以在DML操作之后发生,也可以不发生。触发器与数据库DML操作INSERTUPDATEDELETE相关联。触发器定义为在特定表上执行这些操作时运行。

AFTER触发器

一旦DML操作(例如INSERT)完成,就会执行AFTER触发器。以下是AFTER触发器的一些关键特性:

  • DML操作之后运行触发器之后,例如INSERT语句和任何随后的参考级联操作和约束检查已运行。
  • 您无法使用AFTER触发器取消数据库操作。这是因为该行动已经完成。
  • 可以在表上定义每个动作一个或多个AFTER触发器,但为了简单起见,我建议仅定义一个。
  • 您无法在视图上定义AFTER触发器。

INSTEAD OF触发器

顾名思义,INSTEAD OF触发器代替导致它们触发的DML动作。使用INSTEAD OF触发器时要考虑的事项包括:

  • INSTEAD OF触发器会覆盖触发操作。如果定义一个INSTEAD OF触发器在INSERT语句上执行,那么一旦INSERT语句尝试运行,控制就会立即传递给INSTEAD OF触发器。
  • 最多可以为表的每个操作定义一个INSTEAD OF触发器。这是有道理的,就好像你必须为插入一个“INSTEAD OF”触发器一样,哪一个应该运行?

特殊数据库对象

触发器使用两个特殊的数据库对象INSERTEDDELETED来访问受数据库操作影响的行。在触发器的范围内,INSERTEDDELETE对象具有与触发器表相同的列。

INSERTED表包含所有新值;DELETED表包含旧值。以下是表格的使用方法:

  • INSERT——使用INSERTED表确定将哪些行添加到表中。
  • DELETE——使用DELETED表查看从表中删除的行。
  • UPDATE——使用INSERTED表检查新值或更新值,使用DELETED表查看更新前的值。

定义

为特定表和一个或多个事件定义触发器。在大多数数据库管理系统中,每个表只能定义一个触发器。

以下是AdventureWorks2012数据库的示例触发器。

您会注意到触发器的语法与存储过程的语法非常相似。事实上,触发器使用相同的语言来实现其逻辑,就像存储过程一样。在MS SQL中,这是T-SQL;而在Oracle中则是PL/SQL

以下是触发器的一些重要部分:

  1. CREATE语句——它定义哪个表与触发器相关联。此外,此语句用于指定触发器何时执行(例如插入后)。
  2. 实际的程序。在该示例中,只要将一行或多行插入WorkOrder表,该程序就会运行。
  3. 特殊数据库对象——触发器使用特殊定义的数据库对象(如INSERTEDDELETED)来访问受数据库操作影响的记录。
  4. 在此示例中,触发器使用INSERTED对象来访问新创建的行。INSERT语句用于表示这些行并将它们添加到历史表中。

用于触发器

以下是触发器的一些常见用法:

复杂的审计

您可以使用触发器来跟踪对表所做的更改。在上面的示例中,对WorkOrder表所做的更改将记录在TransactionHistory表中。

通常在创建审计跟踪时,您将使用AFTER触发器。

您可能认为这是多余的,因为数据库日志中记录了许多更改,但日志用于数据库恢复,用户程序无法轻松访问。TransactionHistory表易于引用,可以合并到最终用户报告中。

执行业务规则

触发器可用于在执行DML操作之前检查所有数据。您可以使用INSTEAD OF触发器拦截挂起的DML操作,应用任何业务规则,并最终完成事务。

示例业务规则可以是客户状态定义为:

  • 黄金——过去12个月的购买量超过1,000,000美元。
  • 白银——在过去12个月内购买500,000美元至1,000,000美元。
  • 青铜——所有其他购买水平。

可以定义INSTEAD OF触发器,以便在每次添加或修改客户记录时检查客户状态。状态检查将涉及创建所有客户购买的总和,并确保新状态与过去12个月的购买总和相对应。

派生列值

触发器可用于计算列值。例如,对于每个客户,您可能希望在客户记录上维护TotalSales列。当然,为了保持准确,每次销售时都必须更新。

这可以使用Sales表的INSERTUPDATEDELETE语句上的AFTER触发器来完成。

触发器很棘手!

一般来说,我的建议是避免使用触发器,除非绝对必要。

您应该避免使用触发器代替内置功能。例如,不是依靠触发器来强制执行引用完整性,而是最好使用关系

以下是我回避他们的一些原因:

  1. 他们可能很难排除故障。
  2. 触发器可以触发其他触发器。两个表AB都有一个AFTER UPDATE触发器。如果表A上的AFTER UPDATE触发器更新表B,则更新表A会导致触发,然后B触发。
  3. 你必须确保不会造成触发风暴!你能想象表B由于某种原因更新了表A吗?现在你有一个循环参考......轰!
  4. 我尝试将尽可能多的逻辑移动到存储过程中,并让应用程序通过它们而不是直接的SQL语句来更改数据库。

http://chatgpt.dhexx.cn/article/1UBZ9u1t.shtml

相关文章

Oracle数据库 触发器

文章目录 一、触发器的定义二、触发器的分类三、触发器的功能四、触发器的语法五、触发器的使用案例案例1:向emp1表中插入一条数据后输出 欢迎加入 语句案例2:数据校验,在周四这一天不允许向emp1表中插入/更新数据案例3:创建触发器…

数据库之触发器详解

一、触发器的概念 触发器是与表有关的数据库对象,在满足定义条件时触发,并执行触发器中定义的语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性。 举个例子,比如你现在有两个表【用户表】和【日志表】,当一个…

数据库-触发器

目录 1. 触发器概述 2. 触发器的创建 2.1 创建触发器语法 3. 查看、删除触发器 3.2 删除触发器 4. 触发器的优缺点 4.2 缺点 4.3 注意点 在实际开发中,我们经常会遇到这样的情况:有 2 个或者多个相互关联的表,如 商品信息 和 库存信…

触发器(数据库必学)

文章目录 概念注意 优缺点优点缺点 语法参数说明 查看触发器删除触发器实例实际应用注意重新编辑拓展不能对同一张表进行修改 概念 触发器是一种特殊类型的存储过程,它不同于存储过程,主要是通过事件触发而被执行的。而存储过程则需要主动调用其名字执行…

C语言实现字符串逆序、倒置字符串(字符串逆序问题的升级)

一.字符串逆序 问题描述&#xff1a; 输入一个字符串str&#xff0c;将其内容颠倒过来&#xff0c;并输出。 数据范围0<len(str)<10000 输入描述&#xff1a; 输入一个字符串&#xff0c;可以有空格 输出描述&#xff1a; 输出逆序的字符串 输入样例&#xff1a; …

指针实现字符串逆序

代码如下&#xff1a; #include<stdio.h> #include<string.h> void reverse(char* str) { //指针变量分别指向第一个和最后一个元素&#xff0c;借助中间变量temp进行交换。char* left str;char* right str strlen(str) - 1;while (left < right){char temp…

c语言字符串逆序输出reverse,将一个字符串逆序输出

C语言:输入一个字符串,然后逆序输出 输入一个字符串,然后逆序输出,要CSS布局HTML小编今天和大家分享主函数调用fun函数,fun的功能是逆可以将整数当做字符串(字符串长度不超过10)接收,然后反向输出字符数组元素即可。 字符串实际长度可以用strlen函数来计算。 方法程序如下…

字符串逆序输出

字符串逆置 方法1:下标法&#xff0c;定义一个i下标从头开始&#xff0c;使用strlen函数求出字符串长度(不包括\0),定义一个j下标等于字符串长度减一&#xff0c;i&#xff0c;j下标字符进行交换&#xff0c;只需要遍历字符串长度一半即可 方法2:额外创建一个数组&#xff0c…

递归实现字符串逆序

编写一个函数 reverse_string(char * string)&#xff08;递归实现&#xff09;&#xff0c;将参数字符串中的字符反向排列&#xff0c;不是逆序打印。 &#xff08;要求&#xff1a;不能使用C函数库中的字符串操作函数。&#xff09; &#xff08;在本次练习中&#xff0c;由于…

C字符串逆序、C++字符串逆序

1.C字符串逆序&#xff1a; void CReverse(char* ch) {int nLen strlen(ch) - 1;char szStr;for (int i 0; i < nLen - i; i){szStr ch[i];ch[i] ch[nLen - i];ch[nLen - i] szStr;}ch[nLen 1] 0; } 2.C字符串逆序&#xff08;利用栈的先进后出的原理&#xff09; …

字符串逆序 - 多种方法实现

字符串逆序实现方法 1. 借助额外数组2. 循环实现2.1 图解2.2 思路2.3 代码实现 3. 递归实现14. 递归实现24.1 思路 对字符串进行逆序&#xff0c;以字符串abcdef为例 1. 借助额外数组 #include <stdio.h> #include <string.h>int main() {char str[] "abcd…

字符串逆序的几种写法

字符串逆序的几种写法 提示&#xff1a;将字符串逆序与将其逆序打印出来是两码事&#xff0c;逆序是将内容倒着改变了&#xff0c;逆序打印虽然打印结果也是倒着的&#xff0c;不过储存字符串的数组内容并没有改变。 一、非递归写法 1. 将一个给定的字符串abcdef逆序 #incl…

字符串逆序(递归实现)

目录 一、代码实现&#xff1a; 二、代码逐步实现过程&#xff1a; 1、不用递归用循环方式实现&#xff1a; 1、使用库函数&#xff1a; 2、不使用库函数&#xff1a; &#xff08;1&#xff09;使用参数是数组的形式&#xff1a; &#xff08;2&#xff09;使用参数是指…

【C语言刷题】字符串逆序

目录 一、字符串逆序&#xff08;基础题&#xff09; 1.一个经典的错误&#xff0c;标准的零分 2.采用gets函数来修补漏洞 3.非要使用scanf怎么办&#xff1f; 4.使用指针来实现逆序函数 5.将函数修改为&#xff0c;只要传入两个地址&#xff0c;就能逆序这两个地址之间的…

使用C语言实现字符串逆序操作

这篇文章主要介绍了使用C语言实现字符串逆序操作案例,本文包含使用C语言的两种方法去实现,递归和非递归,以下就是详细内容,需要的朋友可以参考下 编写一个函数 reverse_string(char * string) 实现&#xff1a;将参数字符串中的字符反向排列。 要求&#xff1a;不能使用C函数库…

C语言实现——字符串逆序

目录 前言 如何实现 代码实现 1.设立一个数组存放输入的字符串 2.将输入的字符串整体逆序 2.1 计算字符串长度 2.2 使用函数来实现倒置 2.3 实现函数reverse 3.将其中每个单词再进行逆序 3.1 整个语句如何结束循环 3.2 每个单词的结束位置 3.3 内部实现 3.4 判断…

dtb展开成device_node

dtb展开成device_node 文章目录 dtb展开成device_node设备树是如何传递给内核的&#xff1f;设备树相关结构体举例of操作函数与查找节点有关的 OF 函数1、of_find_node_by_name 函数2、of_find_node_by_type 函数3、of_find_compatible_node 函数4、of_find_matching_node_and_…

设备树之DTS与DTB格式

目录 一、设备树 二、DTS格式 2.1 属性 2.2 节点 2.3 引用其他节点 2.4 小总结 三、DTB格式 3.1 结构 3.2 分析 一、设备树 对于点灯字符设备驱动程序可以有三种写法&#xff0c;首先是传统方法&#xff0c;这种方式直接在程序中写死&#xff0c;其次是利用总线设备驱…

Android boot.img dtb.img 编译过程

最近做RK3588案子,修改dts后,导致boot.img过大,编译出错,整体分析下boot.img过大的原因是因为在打包boot.img过程中,dbt.img过大导致,所以整体分析下boot.img编译过程,尤其是dbt.img的生成过程. boot.img生成过程 在Andorid跟目录下执行, source build/envsetup.sh 然后lunch x…

Linux 设备树(二) dtc dts/dtsi dtb的关系

在学习设备树之前&#xff0c;我们先来了解一下跟设备树相关的三个对象&#xff0c;分别是dtc、dts/dtsi、dtb。 dtc:用来编译设备树的工具 dts:设备树描述文件 dtsi:设备树头文件 dtb:编译后的二进制文件 dtc设备树编译工具 dtc是用来编译设备树的工具&#xff0c;就像gcc可以…