复盘—MySQL触发器实现监听数据表值的变化,对其他数据表做更新
文章目录
- MySQL交换数据库表中两列的值(额外的知识)
- 为防止后面有疑问,提前解释为什么需要 `$$` ?
- 第一版需求
- 第二版需求
- 第三版需求
-
- 注意事项:
- 存在的严重问题
- 最终版
-
- 关键修复说明:
- 完整测试场景:
- 额外建议(如果需要显式处理NULL):
- COALESCE函数
- 业务中出现的问题
MySQL交换数据库表中两列的值(额外的知识)
UPDATE your_table t1, your_table t2
SET t1.column1 = t2.column2,t1.column2 = t2.column1
WHERE t1.id = t2.id
AND your_condition;
以下操作需要注意:确保MySQL用户有创建触发器的权限(TRIGGER权限);注意避免触发器和业务逻辑的递归调用(如:订单表的更新又触发其他触发器)
为防止后面有疑问,提前解释为什么需要 $$
?
-
默认分隔符问题:
-
MySQL 默认使用分号
;
作为语句结束符 -
但触发器/存储过程等包含多个 SQL 语句,内部也有
;
-
如果直接用
;
,MySQL 会在第一个;
就认为语句结束
-
-
解决方案
DELIMITER $$ -- 将结束符临时改为 $$CREATE TRIGGER ... -- 多行触发器定义 BEGIN...; -- 内部语句仍用分号...; END$$ -- 用 $$ 表示整个触发器结束DELIMITER ; -- 恢复默认分隔符
-
具体解析
DELIMITER $$ -- 告诉MySQL:"从现在开始,用$$作为语句结束符"CREATE TRIGGER... -- 开始定义触发器 BEGIN...; -- 触发器内部语句(有分号但不会立即执行)...; END$$ -- 用$$表示整个触发器定义结束DELIMITER ; -- 恢复默认结束符(分号)
-
类比理解
场景 类比 默认分号 ;
句号 .
(结束一个完整句子)创建触发器 写一段包含多个句子的段落 DELIMITER $$
声明:“接下来我要说一大段话,直到听到$$才算结束” END$$
“我说完了($$)” DELIMITER ;
“现在恢复,句号表示句子结束” -
重要提示:
-
$$
不是关键字,可以替换成其他符号(常用//
或%%
)DELIMITER // CREATE TRIGGER ... BEGIN ... END// DELIMITER ;
-
必须成对出现:
开始:
DELIMITER 自定义符号
结束:
自定义符号
+DELIMITER ;
-
只在命令行或脚本中需要:
-
在 MySQL Workbench 等图形工具中通常会自动处理
-
但在 SQL 脚本或命令行中必须显式使用
-
简单说:
$$
就是个"临时盾牌",保护触发器内部的;
不被误认为是结束符,确保整个触发器被完整解析。 -
第一版需求
需要监听订单商品表的中申请中数量的更新,如果更新的值不为0,则需要修改对应订单表中订单的remark字段的值为申请售后中
;
DELIMITER $$CREATE TRIGGER after_order_item_update
AFTER