show warnings;是最快定位data truncated问题的方式,它明确显示哪一列、哪一行被截断及原因;执行insert/update后立即运行该命令,结合select @@sql_mode;判断是否启用严格模式,并用length()查字节数而非字符数来比对字段定义与实际数据。

直接看 SHOW WARNINGS;,它会告诉你哪一列、哪一行、为什么被截断——这是最快定位问题的方式,比猜字段或改代码更可靠。
执行 INSERT/UPDATE 后立刻查警告
MySQL 的 Data truncated for column 在非严格模式下是警告(WARNING),不是错误,容易被忽略。必须在出问题的语句后马上执行:
SHOW WARNINGS;
输出类似:
| Warning | 1265 | Data truncated for column 'name' at row 1 |
说明第 1 行的 name 列被截断了。此时再结合你的 SQL 和实际数据就能快速比对。
- 如果用的是 ORM 或批量导入工具,务必在单条语句后加
SHOW WARNINGS;,别等整个批次跑完 - Navicat、DBeaver 等 GUI 工具默认不显示警告,得手动执行该命令
-
SELECT @@sql_mode;看是否含STRICT_TRANS_TABLES:有则报错中断;无则只警告,但数据已悄悄变短
查字段定义和实际数据长度是否匹配
重点不是“字符串多长”,而是「字节长度」——尤其在 utf8mb4 下,一个中文占 4 字节,VARCHAR(10) 最多存 10 字节,可能连 3 个汉字都放不下。
- 查字段定义:
DESCRIBE table_name;,关注Type列,比如varchar(20)、decimal(8,2)、date - 查实际值长度:
SELECT CHAR_LENGTH('输入值'), LENGTH('输入值');——CHAR_LENGTH是字符数,LENGTH是字节数,后者更关键 - 数值类注意精度:
DECIMAL(5,2)只能存最多 3 位整数 + 2 位小数,123.456会被截成123.45,不四舍五入 - 日期类如
'2026-02-30'或'2026-13-01'也会触发该警告,MySQL 5.7+ 把非法日期归为“截断”
临时关闭严格模式辅助排查
开发环境调试时,可以会话级临时关闭严格模式,让插入先跑通,再靠 SHOW WARNINGS; 暴露所有截断点:
SET sql_mode = '';
然后重跑你的 INSERT。注意:这只是诊断手段,不能上线使用。
- 别改 global sql_mode,影响其他连接
- 生产环境一定保持
STRICT_TRANS_TABLES,否则隐式截断会导致数据丢失而不自知 - ORM 如 Django/MyBatis 可能自动补默认值或转换类型,掩盖原始问题,建议用日志打印最终拼出的 SQL 再验证
- 不同 MySQL 小版本(5.7 vs 8.0)默认
sql_mode不同,Docker 镜像或 RDS 控制台也常预设,务必两边都查SELECT @@sql_mode;
真正麻烦的不是长度不够,而是字段类型和业务逻辑不一致——比如用 ENUM('on','off') 却传了 'enabled',或者前端传了空字符串给 NOT NULL 的 INT 字段。这些不会报 “too long”,但一样触发 Data truncated,且警告信息极简,容易漏掉。











