mysql无内置驼峰转下划线函数,需自定义存储函数逐字符遍历判断大小写边界并插入下划线,兼容5.7+但不处理缩写连写,仅作字符串转换非自动执行ddl。

MySQL里没法直接写驼峰转下划线的内置函数
MySQL本身不提供字符串大小写分割或正则替换的原生函数(REGEXP_REPLACE 8.0+ 才支持,且不支持捕获组回溯),所以不能像 PostgreSQL 那样用 regexp_replace(str, '([a-z])([A-Z])', '\1_\2') 一行搞定。你得自己造一个存储函数,而且得手动遍历字符——这是绕不开的现实。
用存储函数逐字符处理是唯一可行方案
核心思路:遍历输入字符串每个字符,检测当前字符是否为大写字母、且前一个字符是小写字母(即驼峰分界点),如果是,就在前面插入下划线。注意边界情况(开头大写、连续大写如 XMLParser)。
实操建议:
- 声明循环变量
i和结果字符串result,初始值设为空串 - 用
SUBSTRING(str, i, 1)取单个字符,用ASCII()判断是否在 65–90(A–Z)之间 - 检查前一字符是否小写(
ASCII()在 97–122),且当前不是首字符(i > 1) - 连续大写字母要特殊处理:比如
parseXML→parse_xml,但XMLParser应该变成x_m_l_parser还是xml_parser?按主流惯例选后者,需额外判断“当前大写、前一个也大写、再前一个是小写”这种三连模式
简化版函数示例(兼容 5.7+,不处理缩写连写):
DELIMITER $$ CREATE FUNCTION camel_to_snake(str VARCHAR(255)) RETURNS VARCHAR(255) READS SQL DATA DETERMINISTIC BEGIN DECLARE i INT DEFAULT 1; DECLARE result VARCHAR(255) DEFAULT ''; DECLARE c CHAR(1); DECLARE prev_c CHAR(1); WHILE i <h3>调用时注意字符集和性能瓶颈</h3> <p>这个函数在 <code>utf8mb4</code> 下能正常工作,但别在大表 <code>SELECT ... FROM huge_table WHERE camel_to_snake(col) = 'xxx'</code> 里用——它无法走索引,全表扫描不可避免。只适合一次性清洗或应用层预处理。</p> <p>常见错误现象:</p>
- 函数创建失败报错
ERROR 1418:没开log_bin_trust_function_creators=1 - 结果多出下划线,比如
getURL→get_u_r_l:没加连续大写合并逻辑 - 中文或数字字段名传入后乱码或截断:函数声明的
VARCHAR(255)不够长,按实际字段名最大长度调整
更稳妥的做法其实是交给应用层处理
数据库层做命名转换本质是反模式。真正该用的地方,比如生成建表语句、ORM 映射配置、迁移脚本,都建议在 Python/Java/Go 里用成熟正则(re.sub(r'(?)处理。MySQL 函数只是临时救急,别把它当通用工具。
如果你非要在 SQL 里批量改字段名,记得先 SHOW CREATE TABLE 看原始定义,再拼 ALTER TABLE ... RENAME COLUMN ——函数输出只是字符串,不会自动执行 DDL。











