存储过程执行卡住或无响应,大概率是 drop/create 被阻塞,因旧过程仍在被调用且连接未释放,导致 drop procedure if exists 一直等待锁;可通过 performance_schema 查询占用线程并 kill 清理。

存储过程执行卡住或无响应,大概率是 DROP/CREATE 被阻塞
不是语法错了,而是旧过程还在被调用、连接没释放,导致 DROP PROCEDURE IF EXISTS 一直等锁。Workbench 没反应、命令行要 Ctrl+C 才退出,就是典型表现。
查占用线程:SELECT THREAD_ID, SQL_TEXT FROM performance_schema.events_statements_current WHERE SQL_TEXT LIKE '%proc_name%';
再关联 performance_schema.threads 拿到 PROCESSLIST_ID,最后用 KILL <id></id> 干掉它。别急着改代码,先清现场。
裸写 rank、json、window 等字段名直接报错
错误信息 ERROR 1064 near 'rank' 就是明确提示:MySQL 把它当关键字解析了,不是漏逗号。
将音频或视频文件转录为带时间轴的歌词或字幕格式(如LRC、SRT、WebVTT、ASS、TTML),并制作卡拉OK视频。
- 所有出现位置都得加反引号:
`rank`,包括DECLARE变量、SELECT列、UPDATE SET、INSERT INTO (...) VALUES的字段列表 -
SET sql_mode = 'ANSI_QUOTES'不起作用——它只让双引号能当标识符,不影响保留字限制 - ORM 或拼接 SQL 的地方容易漏,比如 Java 里
String.format("SELECT %s FROM t", field),若field是"rank",就得提前处理成"`rank`"
GROUP BY 报错:Expression #1 of SELECT list is not in GROUP BY clause
根本原因是 MySQL 8.0 默认启用 ONLY_FULL_GROUP_BY,而旧版默认关闭。这不是 bug,是 SQL 标准收紧。
- 临时调试可用:
SET SESSION sql_mode = (SELECT REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', '')); - 长期修复优先改 SQL:确保所有非聚合字段出现在
GROUP BY中,或用ANY_VALUE(id)显式包裹 - 别在生产环境全局禁用该模式——它能暴露真实的数据歧义,比如同一分组下
name值不唯一时,结果不可预期
变量未初始化、SELECT ... INTO 查不到就变 NULL、游标 FETCH 顺序错
MySQL 8.0 对变量作用域和流程控制更严格,旧代码“侥幸运行”现在会失效。
-
DECLARE v_total INT DEFAULT 0;必须带DEFAULT,不能依赖隐式补 0 -
SELECT col INTO @var FROM t WHERE id = 999;查不到时@var直接变NULL,不会保留原值 - 游标必须严格按“先
FETCH,再判done”顺序,写成先判后 fetch 会少读一行 - 调试靠
SELECT CONCAT('debug: ', v_var) AS _log;,MySQL 没有PRINT或断点
DEFINER 权限校验变严、log_bin_trust_function_creators 缺失……这些都不是孤立问题。它们往往藏在过程定义深处,导出导入时才集中爆发。最容易被忽略的,是那些多年没动过、连注释都发黄的旧过程——它们不会出现在日常 DDL 检查里,却会在升级后第一个跳出来报错。










