MySQL存储过程与触发器实战技巧
存储过程USE my_suoyin_learning; DELIMITER // CREATE PROCEDURE p11(IN uage INT) BEGIN -- 第1层普通变量 DECLARE uname VARCHAR(100); DECLARE upro VARCHAR(100); DECLARE done INT DEFAULT 0; -- 第2层游标必须放在handler之前 DECLARE u_cursor CURSOR FOR SELECT username,job FROM user_info WHERE ageuage; -- 第3层NOT FOUND异常处理器最后写 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done 1; -- 创建目标表 CREATE TABLE IF NOT EXISTS tb_user_pro( id INT PRIMARY KEY AUTO_INCREMENT , NAME VARCHAR(100), profession VARCHAR(100) ); OPEN u_cursor; WHILE done 0 DO FETCH u_cursor INTO uname,upro; IF done 0 THEN INSERT INTO tb_user_pro VALUES(NULL, uname, upro); END IF; END WHILE; CLOSE u_cursor; END // DELIMITER ; CALL p11(23); SELECT * FROM tb_user_pro;一次性修正全套代码 1、先删掉旧触发器 sql DROP TRIGGER IF EXISTS tb_user_insert_trigger; 2、重新创建日志表统一字段名 sql CREATE TABLE IF NOT EXISTS user_logs ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 日志编号, uid INT COMMENT 新增用户ID, operate_time DATETIME COMMENT 操作时间, action VARCHAR(50) COMMENT 操作类型 ); 3、重新创建触发器字段严格匹配 sql DELIMITER // CREATE TRIGGER tb_user_insert_trigger AFTER INSERT ON user_info FOR EACH ROW BEGIN INSERT INTO user_logs(uid, operate_time, action) VALUES(NEW.id, NOW(), 新增用户); END // DELIMITER ; 4、再次执行插入测试 sql INSERT INTO user_info(id,username,phone) VALUES(10,张三,123456); 5、查看日志是否写入成功 sql SELECT * FROM user_logs; 补充如果你就想用 operation 这个字段名 把建表和触发器统一改成 operation sql DROP TABLE IF EXISTS user_logs; CREATE TABLE user_logs ( id INT PRIMARY KEY AUTO_INCREMENT, uid INT, operate_time DATETIME, operation VARCHAR(50) ); DELIMITER // CREATE TRIGGER tb_user_insert_trigger AFTER INSERT ON user_info FOR EACH ROW BEGIN INSERT INTO user_logs(uid, operate_time, operation) VALUES(NEW.id, NOW(), 新增用户); END // DELIMITER ; 核心规则INSERT 括号里的字段名必须和数据表真实字段完全一模一样一字不差。触发器总结两段触发器代码完整解析整体说明你现在写了两个触发器新增触发器给tb_user插入数据之后自动往日志表user_logs记录插入详情删除触发器给tb_user删除数据之后自动往日志表user_logs记录删除前的数据 用到两个关键字NEWINSERT/UPDATE 触发时代表新增 / 修改后的新数据行OLDDELETE/UPDATE 触发时代表删除 / 修改前的旧数据行第一段插入触发器 tb_user_insert_triggersqlcreate trigger tb_user_insert_trigger after insert on tb_user for each row begin insert into user_logs(id, operation, operate_time, operate_id, operate_params) VALUES (null, insert, now(), new.id, concat(插入的数据内容为: id,new.id,,name,new.name, , phone, NEW.phone, , email,new.email)); end;逐行拆解create trigger tb_user_insert_trigger创建触发器名字tb_user_insert_triggerafter insert on tb_user for each rowafter insert插入 tb_user 数据完成之后再执行触发器for each row每插入一行数据就触发一次begin ... end触发器要执行的 SQL 逻辑体内部插入日志逻辑sqlinsert into user_logs(字段) values(值)表格字段填入内容含义idnull日志主键自增填 null 自动生成operationinsert操作类型新增operate_timenow()当前系统时间operate_idnew.id本次新增用户的 idNEW 刚插入的新行数据operate_paramsconcat 拼接字符串把本次插入的所有字段打包成文本存起来触发场景执行插入语句sqlINSERT INTO tb_user(id,name,phone,email) VALUES(1,张三,13800138000,zsqq.com);tb_user 插入成功瞬间自动在user_logs生成一条插入日志。第二段删除触发器 tb_user_delete_triggersqlcreate trigger tb_user_delete_trigger after delete on tb_user for each row begin insert into user_logs(id, operation, operate_time, operate_id, operate_params) VALUES (null, delete, now(), old.id, concat(删除之前的数据: id,old.id,,name,old.name, , phone, old.phone, , email, old.email, , profession,old.profession)); end;重点区别after delete on tb_user删除 tb_user 数据之后触发必须用 OLD 关键字删除操作数据已经没了只能用OLD获取删除前原本存在的整条数据operation delete标记本次操作为删除concat 把删除前所有字段拼接保存方便后期回溯找回删掉的数据触发场景执行删除语句sqlDELETE FROM tb_user WHERE id1;数据删掉之后自动写入一条删除日志留存删除前完整信息。配套查看命令1. 查看当前库所有触发器你执行的 show triggers;sqlshow triggers;运行后表格会列出触发器名称、触发时机、绑定表、触发语句等信息能验证两个触发器都创建成功。2. 查看日志记录验证触发器有没有生效sqlSELECT * FROM user_logs;插入、删除数据后执行这条语句就能看到自动生成的操作日志。3. 删掉触发器写错需要重建时sqlDROP TRIGGER IF EXISTS tb_user_insert_trigger; DROP TRIGGER IF EXISTS tb_user_delete_trigger;关键知识点总结时机after insert/delete数据操作完毕再记日志一般日志都用 after新旧行关键字新增只有NEW没有 OLD删除只有OLD没有 NEW修改NEW新数据 OLD旧数据都能用concat()MySQL 字符串拼接函数把多个文本、字段拼成一整条日志详情注意你的代码小隐患你没有写DELIMITER改结束符在 Navicat/DataGrip 里大概率会报语法错误。标准完整可运行写法示例sqlDELIMITER // create trigger tb_user_insert_trigger after insert on tb_user for each row begin insert into user_logs(id, operation, operate_time, operate_id, operate_params) VALUES (null, insert, now(), new.id, concat(插入的数据内容为: id,new.id,,name,new.name, , phone, NEW.phone, , email,new.email)); end // DELIMITER ;先把语句结束符临时改成//避免触发器内部的;截断整段创建语句创建完再改回默认;。需要我给你一套完整测试 SQL插入→删除→查看日志你直接复制运行看效果吗和你刚刚写的区别在哪里新旧两套触发器核心区别一、最直观的 5 处差异1. 日志存储内容复杂度不一样我最开始给你的版本 只简单记录操作人 ID、时间、操作文字新增用户内容极简sqlINSERT INTO user_logs(uid, operate_time, action) VALUES(NEW.id, NOW(), 新增用户);你现在这套 把整条插入 / 删除的所有字段全部拼接打包存下来用concat()拼接 id、姓名、电话、邮箱、职业完整详情日志更详细方便后期回溯数据sqlconcat(插入的数据内容为: id,new.id,,name,new.name, , phone, NEW.phone, , email,new.email)2. 字段命名完全不同我初始日志表字段id、uid、operate_time、action你自定义日志表字段id、operation操作类型、operate_time时间、operate_id用户id、operate_params完整参数详情字段命名更贴合开发规范。3. 新增了【删除触发器】我一开始只写了INSERT 插入触发器你现在做了两套完整闭环插入后记录日志删除后记录删除前原始数据日志 覆盖了新增、删除两种数据库操作场景。4. 新旧关键字使用区分核心语法区别1插入场景 两者都只用NEW新数据无区别 2删除场景 只能用OLDOLD.id/ OLD.name代表删掉之前原本存在的数据删除之后数据已经从表消失只能靠 OLD 读取历史内容这是新增触发器没有的语法点。5. 语法细节结束符 DELIMITER 问题我最初完整示例里特意加了DELIMITER //修改语句终止符sqlDELIMITER // 触发器内容 end // DELIMITER ;作用防止触发器内部的分号;提前截断创建语句避免 1064 语法报错 你截图里的代码没有加这段在命令行 MySQL 里会直接语法报错DataGrip 可视化工具做了兼容暂时没报错但标准写法必须带上。二、功能层面区别总结表格版本支持操作日志内容适用场景我最初简易版仅插入 INSERT极简记录用户 ID 时间 操作文字初学理解触发器原理你现在完整版插入 INSERT 删除 DELETE完整存储整条数据详情项目真实审计日志、数据恢复场景三、额外小知识点后续你还可以继续拓展UPDATE 修改触发器 修改数据时可以同时用OLD修改前旧数据NEW修改后新数据记录数据前后变化。四、查看日志的方式没有变化无论日志内容简单还是详细查看语句始终一致sqlSELECT * FROM user_logs;执行后就能看到插入、删除自动生成的全部操作记录。

相关新闻

通信行业分析

通信行业分析

通信工程行业发展趋势分析 核心观察 通信行业正处于结构性转型期。传统电信业务增长放缓,运营商资本开支呈现结构性调整,算力网络投资增长显著,光模块产业链发展活跃,卫星互联网进入快速发展阶段。 ​传统电信增长放缓​&#xff…

2026/10/10 17:11:29 阅读更多 →
射频微波通用仪器原理与测试技术 第五篇

射频微波通用仪器原理与测试技术 第五篇

第五篇 矢量网络分析仪 VNA:测“反射和传输”30. VNA 为什么叫“矢量”网络分析仪VNA Vector Network Analyzer。它不只测信号有多大,还测相位,因此结果是“矢量/复数”。它内部有扫频源、定向耦合器或桥路、参考接收机和测量接收机。源发出…

2026/10/10 17:11:17 阅读更多 →
【零基础】2026主流AI大模型API调用完整教程

【零基础】2026主流AI大模型API调用完整教程

文章目录前言一、OpenAI GPT API 调用二、Google Gemini API 调用三、Anthropic Claude API 调用四、DeepSeek API 调用五、阿里 Qwen API 调用六、xAI Grok API 调用七、六大模型 API 接口与 SDK 对比八、多模型接入解决方案九、大模型 API 常见报错与排查十、总结前言 本文整…

2026/10/10 3:48:10 阅读更多 →

最新新闻

Pandoc 老将 vs MarkItDown 新王:AI 数据流水线到底该选谁?

Pandoc 老将 vs MarkItDown 新王:AI 数据流水线到底该选谁?

Pandoc 老将 vs MarkItDown 新王:AI 数据流水线到底该选谁? 【免费下载链接】markitdown Python tool for converting files and office documents to Markdown. 项目地址: https://gitcode.com/GitHub_Trending/ma/markitdown 把一份 50 页的 PD…

2026/10/10 20:34:19 阅读更多 →
微电网日前经济调度Matlab建模:储能与需求响应详解

微电网日前经济调度Matlab建模:储能与需求响应详解

前段时间我在做微电网日前经济调度相关课题的时候,把风电、光伏、储能和需求响应全部塞进了同一个24小时优化模型里,用Matlab完成建模和求解。说实话,刚接触这类题目时,很多人会觉得无非就是列约束、调求解器,但真正把…

2026/10/10 20:34:19 阅读更多 →
Flask+Vue构建医院康复预约系统:设计与实现

Flask+Vue构建医院康复预约系统:设计与实现

1. 项目概述与整体设计思路1.1 医院康复预约到底在解决什么问题康复科这个场景很有意思,它跟普通门诊挂号有本质区别。普通挂号只需要科室、医生、时间三个信息;康复预约则多出了"项目归属"和"疗程连续性"。一个脑卒中恢复期的患者&…

2026/10/10 20:34:19 阅读更多 →
基于Spring Boot+Vue的校园互助交易平台开发实战

基于Spring Boot+Vue的校园互助交易平台开发实战

1. 选题拆解:校园互助交易平台到底在研究什么1.1 从一个很朴素的痛点说起高校里的闲置物品交易、二手教材买卖、代取快递、拼车拼单、技能互助,这些需求在校园里是真实存在且高频发生的。但当前大部分信息的流转方式是QQ群、微信群、表白墙、朋友圈&…

2026/10/10 20:34:19 阅读更多 →
Linux命令高效学习:从知识框架到组合实战

Linux命令高效学习:从知识框架到组合实战

1. 先建立整体认识:Linux命令到底该怎么学很多人一提到Linux命令,第一反应就是“记不住”,然后是“命令太多太杂,不知从何下手”。这其实是刚入门时最常见的误区。Linux命令看起来成千上万,但抛开那些一年都用不上一两…

2026/10/10 20:34:19 阅读更多 →
一个人 = 50人游戏工作室?我发现了AI游戏开发的终极答案

一个人 = 50人游戏工作室?我发现了AI游戏开发的终极答案

文章目录 一、你有没有想过,一个人也能运营一家游戏公司? 二、功能全景图:这不是一个工具,是一整套操作系统 三、三层代理架构:完美复刻游戏大厂的组织设计 3.1 架构总览 3.2 每一层到底干什么? 3.3 协作规则:AI不会乱打架的秘密 四、模块架构图:五大组件如何协同工作 …

2026/10/10 20:33:18 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:25 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →