mysql 8.0 将 rank、json 等词列为强制保留字,裸用会报错;drop procedure 卡住因旧过程被调用未释放锁;所有出现位置须加反引号,orm 和字符串拼接易漏,可用 information_schema.keywords 批量检测。

rank、json、window、recursive 这类词在 MySQL 5.6 里只是普通标识符,到了 8.0 被正式列为**强制保留字**,存储过程一解析就报错 —— 不是语法写错了,是词义变了。
为什么 DROP/CREATE PROCEDURE 会卡住不动?
不是代码问题,是锁没释放。旧过程正在被应用调用,连接没断,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 字段名为什么会报 ERROR 1064?
MySQL 8.0 解析器看到 rank 就按关键字处理,根本不会去查你是不是变量或字段名。
- 所有出现位置都得加反引号:
`rank`,包括DECLARE、SELECT列、UPDATE SET、INSERT INTO ... VALUES的字段列表 -
SET sql_mode = 'ANSI_QUOTES'无效:它只让双引号能当标识符,不绕过保留字限制 - ORM 或字符串拼接(如 Java 的
String.format("SELECT %s FROM t", field))最容易漏,field是"rank"时必须提前转成"`rank`"
怎么批量发现存储过程里的保留字风险?
别靠人眼扫,MySQL 自带权威清单:INFORMATION_SCHEMA.KEYWORDS。
- 执行:
SELECT WORD FROM INFORMATION_SCHEMA.KEYWORDS WHERE RESERVED = 1 AND WORD IN ('rank','json','window','recursive','role'); - 拿到当前版本的强制保留字列表后,导出所有过程定义:
SELECT ROUTINE_NAME, ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'your_db'; - 用 grep 或脚本搜索这些词是否裸出现(没包反引号)











