之前介绍的语句和存储过程,都需要被执行。而触发器用于当条件满足时自动执行某条语句或某些语句,比如顾客表插入时自动检查电话格式是否正确,订购产品时从库存中减去订购的数量等。
1 触发器
建议尽量少用触发器,如果有更好的方法最好不用触发器。因为触发器是针对每一行的;若是对增删改非常频繁的表上使用触发器,它将会非常消耗资源。
1.1 创建触发器
CREATE TRIGGER 触发器名 BEFORE|AFTER 触发事件
ON 表名 FOR EACH ROW
BEGIN
执行语句列表
END;
-- 触发器名必须唯一
-- 只有表才支持触发器,视图不支持触发器
-- 触发事件支持INSERT、DELETE、UPDATE三种操作,支持AFTER、BEFORE两种触发时间
-- BEGIN..END用于封装执行语句列表,若执行语句只有一条则可以省略
-- 5.7之后引入trigger_order,用于定义多个触发器,使用follows和precedes来选择触发器执行的先后顺序复制
1.2 查询触发器
SHOW TRIGGERS;
-- 显示所有触发器
SELECT * FROM information_schema.`TRIGGERS`复制
1.3 删除触发器
DROP TRIGGER 触发器名;
-- 触发器不支持更新或覆盖,若需要修改,必须先删除复制
2 INSERT型触发器
插入某一行时激活触发器,可能通过INSERT、LOAD DATA、REPLACE 语句触发(LOAD DAT语句用于将一个文件装入到一个数据表中,相当于一系列的INSERT操作)。
可以用NEW.columnName获取将要(BEFORE)或已经(AFTER)插入的新数据,NEW可以使用SET进行赋值而又不触发触发器,从而导致循环调用。
CREATE TABLE IF NOT EXISTS account (acct_num INT, amount DECIMAL(10,2));
TRUNCATE TABLE account;
-- 创建表(若表不存在)并清空
delimiter $$
CREATE TRIGGER ins_check BEFORE INSERT ON account
FOR EACH ROW
BEGIN
IF NEW.amount < 0 THEN
SET NEW.amount = 0;
ELSEIF NEW.amount > 100 THEN
SET NEW.amount = 100;
END IF;
END$$
delimiter ;
-- 创建触发器,若插入的amount<0则改为0;>100则改为100
-- AFTER不能对NEW进行修改,BEFORE可以对NEW进行修改
INSERT INTO account VALUES(137,14.98),(141,1937.50),(97,-100.00);
select * from account;
-- 插入数据并验证效果
DROP TRIGGER ins_check;
-- 使用完建议删除复制
3 UPDATE型触发器
更改某一行时激活触发器,可能通过UPDATE语句触发
可以用OLD.columnName获取将要(BEFORE)或已经(AFTER)被修改的原数据;NEW.columnName获取将要(BEFORE)或已经(AFTER)被修改的新数据。OLD是只读的,而NEW可以使用SET进行赋值而又不再次触发触发器,从而导致循环调用。
CREATE TABLE IF NOT EXISTS account (acct_num INT, amount DECIMAL(10,2));
TRUNCATE TABLE account;
-- 创建表(若表不存在)并清空
INSERT INTO account VALUES(137,14.98);
-- 插入数据
delimiter $$
CREATE TRIGGER upd_check BEFORE UPDATE ON account
FOR EACH ROW
BEGIN
IF NEW.amount < 0 THEN
SET NEW.amount = 0;
ELSEIF NEW.amount > 100 THEN
SET NEW.amount = 100;
END IF;
END$$
delimiter ;
-- 创建触发器,当表更新时执行BEGIN..END之间的动作(若更新后的amount<0则改为0;>100则改为100)
-- AFTER不能对NEW进行修改,BEFORE可以对NEW进行修改;二者都不能对OLD进行修改
update account set amount=-10 where acct_num=137;
select * from account;
-- 更新amount为-10,验证是否修改为0
update account set amount=200 where acct_num=137;
select * from account;
-- 更新amount为200,验证是否修改为100
DROP TRIGGER upd_check;
-- 使用完建议删除复制
4 DELETE型触发器
删除某一行时激活触发器,可能通过DELETE、REPLACE语句触发。
可以通过OLD.columnName获取将要(BEFORE)或已经(AFTER)被删除的数据,OLD是只读的。
CREATE TABLE IF NOT EXISTS account (acct_num INT, amount DECIMAL(10,2));
CREATE TABLE IF NOT EXISTS account_records(acct_num INT,records INT);
TRUNCATE TABLE account;
TRUNCATE TABLE account_records;
-- 创建表(若表不存在)并清空
INSERT INTO account VALUES(137,14.98),(141,1937.50),(97,-100.00);
INSERT INTO account_records VALUES(137,1),(141,1),(97,1);
-- 插入数据
delimiter $$
CREATE TRIGGER del_check AFTER DELETE ON account FOR EACH ROW
BEGIN
UPDATE account_records
SET records = records - 1
WHERE
acct_num = OLD.acct_num ;
END$$
delimiter ;
#创建触发器,当表account中删除记录时,account_records中对应的records值将减1
DELETE FROM account where acct_num=137;
select * from account_records;
#删除数据并验证效果
DROP TRIGGER del_check;
-- 使用完建议删除复制
文章转载自lin在路上,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
2025年4月中国数据库流行度排行榜:OB高分复登顶,崖山稳驭撼十强
墨天轮编辑部
1254次阅读
2025-04-09 15:33:27
2025年3月国产数据库大事记
墨天轮编辑部
719次阅读
2025-04-03 15:21:16
2025年3月国产数据库中标情况一览:TDSQL大单622万、GaussDB大单581万……
通讯员
518次阅读
2025-04-10 15:35:48
征文大赛 |「码」上数据库—— KWDB 2025 创作者计划启动
KaiwuDB
453次阅读
2025-04-01 20:42:12
数据库,没有关税却有壁垒
多明戈教你玩狼人杀
402次阅读
2025-04-11 09:38:42
优炫数据库成功应用于国家电投集团青海海南州新能源电厂!
优炫软件
380次阅读
2025-03-21 10:34:08
天津市政府数据库框采结果公布!
通讯员
304次阅读
2025-04-10 12:32:35
最近我为什么不写评论国产数据库的文章了
白鳝的洞穴
297次阅读
2025-04-07 09:44:54
从HaloDB体验到国产数据库兼容性
多明戈教你玩狼人杀
266次阅读
2025-04-07 09:36:17
OceanBase 单机版发布,针对中小规模业务场景
通讯员
230次阅读
2025-03-28 12:01:19