MySQL 5.7升级到8.0后,JSON_EXTRACT、GROUP_CONCAT、CAST、STR_TO_DATE函数行为变化最常导致线上查询失败或结果错乱:JSON_EXTRACT默认仍带引号需改用->>操作符;GROUP_CONCAT严格按group_concat_max_len截断,默认1024易不足;CAST/CONVERT在严格模式下对非法日期或精度超限直接报错而非静默处理;STR_TO_DATE格式容错性下降,非标准格式或无效日期更易报错。

MySQL 5.7升级到8.0后,JSON_EXTRACT、GROUP_CONCAT、CAST、STR_TO_DATE 这几类函数的行为变化最常导致线上查询失败或结果错乱——不是语法报错,而是返回值逻辑变了。
JSON_EXTRACT 返回值自动去引号(→ ->>)
5.7中JSON_EXTRACT(json_col, '$.name')返回带双引号的字符串"Alice";8.0默认仍返回带引号,但多数应用代码直接拼接或比较时没处理引号,结果匹配失败。
- 正确写法(8.0推荐):
json_col->>'$.name',->>是JSON_UNQUOTE(JSON_EXTRACT(...))的简写,直接吐纯文本 - 别硬套5.7习惯:
TRIM(BOTH '"' FROM JSON_EXTRACT(...))在8.0里冗余且易漏空格 - 注意嵌套数组:
json_col->>'$.tags[0]'能取首项值,但json_col->'$.tags[0]'仍带引号,容易误判类型
GROUP_CONCAT 默认被截断(group_concat_max_len 影响变大)
8.0对GROUP_CONCAT更“较真”:即使你没显式设group_concat_max_len,它也严格按会话级变量值截断,而5.7有时会悄悄绕过。
- 查当前限制:
SELECT @@group_concat_max_len;,默认值1024(远小于业务常见需求) - 临时改(当前会话):
SET SESSION group_concat_max_len = 1000000; - 长期方案:在
my.cnf里加group_concat_max_len = 4194304(4MB),重启生效 - 别只改GLOBAL:
SET GLOBAL不影响已存在的连接,必须连上后SET SESSION或重启连接池
CAST 和 CONVERT 对时间/数字精度更严格
5.7对CAST('2023-02-30' AS DATE)可能转成NULL或静默修正为2023-02-28;8.0默认严格模式下直接报ERROR 1292。
- 典型报错:
ERROR 1292 (22007): Truncated incorrect date value: '2023-02-30' - 检查是否启用严格模式:
SELECT @@sql_mode;含STRICT_TRANS_TABLES就会拦截 - 安全兜底:
STR_TO_DATE('2023-02-30', '%Y-%m-%d')返回NULL不报错,比CAST更柔韧 - 数值场景:
CAST('123.456789' AS DECIMAL(5,2))在5.7四舍五入为123.46,8.0可能截断为123.45(取决于sql_mode和版本补丁)
STR_TO_DATE 格式符容错性下降
5.7接受STR_TO_DATE('2023/13/01', '%Y/%m/%d')返回NULL;8.0在严格模式下直接报错,且%k(无前导零小时)等非标准格式符支持更差。
- 验证方式:
SELECT STR_TO_DATE('2023/13/01', '%Y/%m/%d');在8.0返回NULL还是报错,取决于sql_mode - 生产建议:统一用
DATE_FORMAT(NOW(), '%Y-%m-%d')生成字符串,避免反向解析不可靠输入 - 别依赖隐式转换:像
WHERE date_col = '2023-13-01'在5.7可能不报错但查不到,在8.0直接ERROR 1292
这些函数变化往往藏在旧SQL深处,不会立刻报错,但某天数据格式稍变就崩——尤其JSON_EXTRACT和GROUP_CONCAT,最容易在报表或导出逻辑里翻车。升级后务必跑一遍含JSON字段和分组拼接的业务SQL,别只看DDL兼容性报告。


















