13.触发器

目录

1、创建触发器

1、创建只有一个执行语句的触发器

2、创建有多个执行语句的触发器

2、查看触发器

1、通过SHOW TRIGGERS查看触发器:

2.在triggers 表中查看触发器信息

3、使用触发器

4、删除触发器


1、创建触发器

MySQL 的触发器和存储过程一样,都是嵌入到 MySQL的一段程序。

触发器是由事件来触发某个操作,这些事件包括INSERT、UPDATAE和DELETE语句。

如果定义了触发程序,当数据库执行这些语句的时候就会激发触发器执行相应的操作,

触发程序是与表有关的命名数据库对象,当表上出现特定事件时,将激活该对象。

触发器(trigger)是个特殊的存储过程,不同的是,执行存储过程要使用CALL语句来调用, 而触发器的执行不需要使用 CALL 语来调用,也不需要手工启动,只要当一个预定义的

事件发生的时候就会被MySQL自动调用。比如当对fuits表进行操作(INSERT DELETE

或UPDATE)时就会激活它执行。

触发器可以查询其他表,而且可以包含复杂的 SQL 语句。

它们主要用于满足复杂的业务规则或要求。

例如:可以根据客户当前的账户状态,控制是否允许插入新订单。

1、创建只有一个执行语句的触发器

创建一个触发器的语法如下:

CREATE TRIGGER trigger_name trigger_time trigger_event

ON tbl_name FOR EACH ROW trigger_stmt

其中

trigger_name标识触发器名称,用户自行指定;

trigger_time 标识触发时机,可以指定为 before 或after;

trigger_event 标识触发事件包括 INSERT UPDATE 和 DELETE;

tbl_name标识建立触发器的表名,即在哪张表上建立触发器;

trigger_stmt 是触发器执行语句。

举例:创建一个单执行语句的触发器,代码如下:

create table  account (acct_num int,amount decimal(10,2)); /*建立一个临 
时账号表*/ 

create trigger ins_sum before insert 
on account
for each row set @sum=@sum+new.amount;

首先创建一个account表,表中有两个字段,分别为:acct_num字段(定义为int类型),

amount 字段(定义成浮点类型):其次创建一个名为 ins_sum 的触发器, 触发的条件是向数据表account插入数据之前,对新插入的amount字段值进行求和计算。

测试一下:

set @sum=0;
insert into account values(1,123.12),(2,321.21);
select @sum;

2、创建有多个执行语句的触发器

创建多个执行语句的触发器的语法如下:

CREATE TRIGGER trigger_name trigger_time trigger_event

ON tbl_name FOR EACH ROW

BEGIN

语句执行列表

END

其中 trigger_name标识触发器的名称,用户自行指定;trigger_time标识触发时机,

可以指定为 before 或after;trigger_event 标识触发事件,包括INSERT、UPDATE和

DELETE:

tbl_name标识建立触发器的表名,即在哪张表上建立触发器:

触发器程序可以使用BEGIN和END作为开始和结束,中间包含多条语句。

举例:创建一个包含多个执行语句的触发器,代码如下:

创建表

create table test1(a1 int);
create table test2(a2 int); 
create table test3(a3 int not null AUTO_INCREMENT primary key); 
create table test4( 
a4 int not null AUTO_INCREMENT primary key, 
b4 int default 0 
); 

创建触发器

delimiter //
create trigger testref  before insert on test1
for each row 
begin
insert into test2 set a2 = new.a1;
delete from test3 where a3 = new.a1;
update test4 set b4=b4+1 where a4=new.a1;
end //
delimiter ;

初始化一些数据

INSERT INTO test3 (a3) VALUES 
(NULL),(NULL),(NULL),(NULL),(NULL), 
(NULL),(NULL),(NULL),(NULL),(NULL); 
INSERT INTO test4 (a4) VALUES (0),(0),(0),(0),(0), (0),(0),(0),(0),(0); 

上面的代码是创建了一个名为 testref 的触发器,

这个触发器的触发条件是在向表 test1插入数据前执行触发器的语句,

具体执行的代码如下:

开始前:

执行如下插入操作,会自动触发触发器完成test2,test3,test4 表的自动变更。

insert into test1 values (1),(3),(1),(7),(1),(8),(4),(4); 

那么4个表中数据如下:

执行结果显示,在向表test1 插入记录的时候,test2、test3、test4 都发生了变化。

从这个例子看INSERT触发了触发器,向 test2 中插入了 test1 中的值,

删除了test3 中相同的内容同时更新了test4中的b4,即与插入的值相同的个数。

查看触发器是指查看数据库中已存在的触发器的定义、状态和语法信息等。

2、查看触发器

可以通过命令来查看已经创建的触发器。

两种查看触发器的方法,分别是:SHOW TRIGGERS 和在triggers表中查看触发器信息。

1、通过SHOW TRIGGERS查看触发器:

show triggers;

通过SHOW TRIGGERS命令查看一个触发器,代码如下:

show triggers \G;

创建一个简单的触发器,名称为 trig_update,每次向account表更新数据之后都会向

名称为myevent的数据表中插入一条记录,数据表myevent定义如下:

create table myevent   
( 
id int(11) default null, 
evt_name char(20) default null 
); 

创建触发器的执行代码如下

create trigger trig_update before insert on account
for each row 
insert into myevent values (1,'after update'); 

使用SHOW TRIGGERS \G 命令查看触发器

Trigger表示触发器的名称 在这里两个触发器的名称分别为ins_sum和trig_update;

Event表示激活触发器的事件 这里的两个触发事件为插入操作INSERT 和更新操作

UPDATE;

Table表示激活触发器的操作对象表,这里都为 account表;Timing表示触发器触发的时

间,

分别为插入操作之前(BEFORE和更新操作之后(AFTER);Statement 表示触发器执行的

操作

还有一些其他信息,比如 SQL 的模式、触发器的定义账户和字符集等,这里不再一一

介绍。

2.在triggers 表中查看触发器信息

在MySQL中所有触发器的定义都存在INFORMATION_SCHEMA数据库的

TRIGGERS表格中,

可以通过查询命令SELECT来查看,具体的语法如下:

SELECT  FROM  INFORMATION_SCHEMA.TRIGGERS  WHERE  Condit1on;

举例:

select * from INFORMATION_SCHEMA.TRIGGERS where TRIGGER_NAME= 'ins_sum'\G; 

从上面的执行结果可以得到:TRIGGER_SCHEMA 表示触发器所在的数据库;

TRIGGER_NAME 后面是触发器的名称,

EVENT_OBJECT_TABLE表示在哪个数据表上触 发

ACTION_STATEMENT表示触发器触发的时候执行的具体操作

ACTION_ORIENTATION是ROW,表示在每条记录上都触发:

ACTION_TIMING表示触发的时刻是 AFTER,剩下的是和系统相关的信息。

也可以不指定触发器名称,这样将查看所有的触发器,命令如下:

select * from INFORMATION_SCHEMA.TRIGGERS \G; 

这个命令会显示这个TRIGGERS表中所有的触发器信息。

3、使用触发器

使用触发器:

触发程序是与表有关的命名数据库对象,当表上出现特定事件时,将激活该对象。

在某些触发程序的用法中,可用于检查插入到表中的值,或对更新涉及的值进行计算。

触发程序与表相关,当对表执行INSERT、DELETE或UPDATE语句时,将激活触发程序。

可以将触发程序设置为在执行语句之前或之后激活。

例如,可以在从表中删除每一行之前或在更新每一行之后激活触发程序。

创建一个在account 表插入记录之后,更新myevent 数据表的触发器,代码如下:

create table myevent (id int, log text); 
create trigger trig_insert after insert
on account
for each row
insert into myevent values(2,'after insert');

上面的代码创建了一个trig_insert的触发器在向表account插入数据之后会向表myevent

插入一组数据,代码执行如下:

insert into account values (1,1.00), (2,2.00);
select * from myevent;

从执行的结果来看,是创建了一个名称为 trig insert 的触发器,

它是在向account 插入记录之后进行触发,执行的操作是向表myevent插入一条记录。

4、删除触发器

使用DROP TRIGGER 语句可以删除MySQL中已经定义的触发器

删除触发器语句基本语法格式如下:

DROP TRIGGER [schema_name.] trigger_name

其中,schema_name表示数据库名称,是可选的。如果省略了schema,

将从当前数据库中舍弃触发程序;trigger_name 是要删除的触发器的名称。

举例:删除一个触发器,代码如下:

DROP TRIGGER test.ins;

上面的代码中test 是触发器所在的数据库,ins 是一个触发器的名称。代码执行如下:

drop trigger test.trig_insert;

触发器trig_insert删除成功。

查询确认已经删除:

show triggers \G;

注意事项:

疑问1:使用触发器时须特别注意

在使用触发器的时候需要注意,对于相同的表,相同的事件只能创建一个触发器,

比如对表account创建了一个BEFORE INSERT触发器那么如果对表account再次

创建一个BEFORE INSERT触发器,MySQL将会报错,此时,只可以在表account

上创建AFTER INSERT或者BEFORE UPDATE类型的触发器。灵活地运用触发器将为操作省去很多麻烦。

疑问2:及时删除不再需要的触发器

触发器定义之后,每次执行触发事件,都会激活触发器并执行触发器中的语句。

如果需求发生变化,而触发器没有进行相应的改变或者删除,则触发器仍然会执行旧的语

句,从而会影响新的数据的完整性。因此,要将不再使用的触发器及时删除。

练习题:

(1)创建INSERT事件的触发器

create table a (id int, yeat int); 
create table a1 (id int, log text); 
select * from a1;
create trigger trig_a1 after insert
on a
for each row
insert into a1 values(2,'after insert');

insert into a values (1,100), (2,200);
select * from a1;

(2)创建UPDATE事件的触发器。

create trigger trig_a2 after update
on a
for each row
insert into a1 values(3,'after insert');

update a 
set id = 2, yeat=100
where id = 2;
select * from a1;

(3)创建DELETE事件的触发器。

create trigger trig_a3 after delete
on a
for each row
insert into a1 values(4,'after insert');

delete from a where id = 2;
select * from a1;

(4)查看触发器,并使用触发器。

show triggers \G;

select * from INFORMATION_SCHEMA.TRIGGERS where TRIGGER_NAME= 'trig_a2'\G; 

(5)删除触发器。

drop trigger trig_a3;

select * from INFORMATION_SCHEMA.TRIGGERS where TRIGGER_NAME= 'trig_a3'\G; 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/234105.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AttributeError: ‘bool‘ object has no attribute ‘sum‘

AttributeError: ‘bool’ object has no attribute ‘sum’ AttributeError: ‘bool’ object has no attribute ‘sum’ 解决方法 将torch.max()改为torch.argmax()查看output和targets的数据类型是否都为tensor 以上就是全部内容&#…

CSS 实现丝滑动画

效果展示 CSS 知识点 animation 综合运用 页面整体布局 <div class"box"><div class"circle"></div> </div>编写基础样式 .box {position: relative;width: 400px;height: 400px;border: 80px solid transparent;border-left:…

JDK8新特性:Lambda表达式规则及用法,方法引用

目录 Lambda表达式是JDK8新增的一种语法格式 1.作用 2.用法规则&#xff1a; 3.方法引用 Lambda表达式是JDK8新增的一种语法格式 1.作用 简化匿名内部类的代码写法 Lambad用法前提&#xff1a;只能简化函数式接口&#xff08;一般加有Funcationallnterface&#xff09;&a…

虚拟机VMware安装centos以及配置网络

目录 1、CentOS7的下载2、CentOS7的配置3、CentOS7的安装4、CentOS7的网络配置 4.1、自动获取IP4.2、固定获取IP 5、XShell连接CentO 准备工作&#xff1a;提前下载和安装好VMware。VMware的安装可以参考这一篇文章&#xff1a;VMware15的下载及安装教程。 1、CentOS7的下载 …

排序算法---选择排序

1.实现流程&#xff1a; 1. 把第一个没有排序过的元素设置为最小值&#xff1b; 2. 遍历每个没有排序过的元素&#xff1b; 3. 如果元素 < 现在的最小值&#xff1b; 4. 将此元素设置成为新的最小值&#xff1b; 5. 将最小值和第一个没有排序过的位置交换 选择排序执行流程…

数据的存储(类型的提升)

在操作负中&#xff0c;我们讲解过整形提升运算符&#xff08;详情请看写文章-CSDN创作中心操作符&#xff08;原码反码补码&#xff09;-CSDN博客写文章-CSDN创作中心&#xff09;&#xff0c;知道CPU都是基于整形运算的&#xff0c;而且每个类型都有其最大存储的整数。 目录…

32.768KHz时钟RTC晶振精度PPM值及频差计算

一个数字电路就像一所城市的交通&#xff0c;晶振的作用就是十字路口的信号灯&#xff0c;因此晶振的品质及其电路应用尤其关键。数字电路又像生命体&#xff0c;它的运行就像人身体里的血液流通&#xff0c;它不是由单一的某个器件或器件单元构成&#xff0c;而是由多个器件及…

【数据结构 — 排序 — 交换排序】

数据结构 — 排序 — 交换排序 一.交换排序1.基本思想2.冒泡排序2.1.算法讲解2.2.代码实现2.2.1.函数定义2.2.2.算法接口实现2.2.3.测试代码实现2.2.4.测试展示 3.快速排序3.1.算法讲解3.2.各大算法分别单独实现3.2.1快速排序hoare版本3.2.2.快速排序hoare改进版三数取中选key法…

基于OpenCV的流水线包装箱检测计数应用(附源码)

导 读 本文主要介绍基于OpenCV的流水线包装箱检测计数应用,并给出源码。 资源下载 完整代码和视频下载地址: https://github.com/freedomwebtech/rpi4-conveyor-belt-boxces-counter 核心代码如下(cboxtest.py): import cv2import numpy as npfrom tracker import*cap=c…

class067 二维动态规划【算法】

class067 二维动态规划 code1 64. 最小路径和 // 最小路径和 // 给定一个包含非负整数的 m x n 网格 grid // 请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 // 说明&#xff1a;每次只能向下或者向右移动一步。 // 测试链接 : https://leetcode…

Fortran读取netcdf文件/WRF中的文件读取

一直很好奇WRF到底如何通过netcdf库读取netcdf文件&#xff0c;正巧有个机会&#xff0c;试了下fortran读取nc文件&#xff0c;总结一下。 netcdf库 Fortran读取nc文件需要依赖netcdf外部库。安装该库以后&#xff0c;会有专门写给ffortran函数声明的头文件&#xff1a;netcd…

RC522(RFID射频模块)读卡ID的简单应用

文章目录 一、RFID是什么&#xff1f;二、RC522模块三、使用步骤1.硬件1.硬件连接2.引脚定义 2.软件1.初始化配置代码如下&#xff08;示例&#xff09;&#xff1a;2.引脚配置代码如下&#xff08;示例&#xff09;&#xff1a;3.模块复位代码如下&#xff08;示例&#xff09…

【工具】JS|浏览器脚本6分钟极速入门 · 开发一个限制自己刷b站的脚本

这张图花里胡哨的是让AI生成的&#xff0c;我觉得怪可爱的&#xff0c;就直接作为封面了。 这篇文章中会开发一个JS脚本&#xff0c;这是一个用来限制b站网页版功能的脚本&#xff0c;避免刷b站的时间过长。功能如下&#xff1a; 除了搜索、视频页、私信页之外的任何页都会被重…

Vue3:修改下拉框el-select的样式

问题 在Vue3项目中&#xff0c;使用了elemen-plus的下拉框&#xff0c;但是使用深度修改下拉框的样式&#xff08;比如下拉框的背景颜色&#xff09;一直不生效 解决 给下拉框框添加 popper-class属性&#xff0c;属性名根据需求取&#xff0c;比如这里取的是"selectSt…

【Docker】进阶之路:(一)容器技术发展史

【Docker】进阶之路&#xff1a;&#xff08;一&#xff09;容器技术发展史 什么是容器为什么需要容器容器技术的发展历程Docker容器是如何工作的 什么是容器 容器作为一种先进的虚拟化技术&#xff0c;已然成为了云原生时代软件开发和运维的标准基础设施。在了解容器技术之前…

【LeetCode刷题】-- 137.只出现一次的数字II

137.只出现一次的数字II class Solution {public int singleNumber(int[] nums) {Map<Integer,Integer> map new HashMap<>();for(int num : nums){Integer count map.get(num);if(count null){count 1;}else{count;}map.put(num,count);}for(Integer val:map.…

2023年安全员-B证证考试题库及安全员-B证试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年安全员-B证证考试题库及安全员-B证试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大纲随机出的…

LeetCode---374周赛

题目列表 2951. 找出峰值 2952. 需要添加的硬币的最小数量 2953. 统计完全子字符串 2954. 统计感冒序列的数目 一、找到峰值 这个简单的模拟&#xff0c;代码如下 class Solution { public:vector<int> findPeaks(vector<int>& mountain) {int nmountain…

【附源码】完整版,Python+Selenium+Pytest+POM自动化测试框架封装

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、测试框架简介 …

[每周一更]-(第76期):Go源码阅读与分析的方式

读源码可以深层理解Go的编写方式&#xff0c;理解作者们的思维方式&#xff1b;也有助于对Go语法用法深刻的理解&#xff0c;我们从这一篇说一下如何读源码&#xff0c;从哪些源码着手&#xff0c;从 简单到深入的方式学习源码&#xff1b; 学习源码也是一个修炼过程&#xff0…
最新文章