MySQL · 错误码速查
MySQL 错误 1406:值比列定义长,严格模式下整条语句不写入
Data too long for column 'title' at row 1 说明写入值超过了列长度。VARCHAR(N) / CHAR(N) 的 N 是字符数(测试库 VARCHAR(10) 能存 10 个汉字),TEXT 的上限是 65535 字节(utf8mb4 下 21845 个汉字)。at row N 指本条语句里的第 N 行。严格模式(8.4 默认含 STRICT_TRANS_TABLES)下整条语句失败;关掉严格模式或用 INSERT IGNORE 不会报错,但数据会被静默截断——这比报错更危险。
官方原文
Data too long for column '%s' at row %ld官方错误参考:Error number 1406;Symbol ER_DATA_TOO_LONG;SQLSTATE 22001。
出处:MySQL 8.4 Error Reference:Server Error Message Reference 最后核对:
| 错误号 / 符号 | 1406 / ER_DATA_TOO_LONG | 出处 |
|---|---|---|
| SQLSTATE | 22001(字符串数据右截断) | 出处 |
| VARCHAR/CHAR 长度单位 | 字符:VARCHAR(10) 存 10 个汉字成功,LENGTH 为 30 字节 | 出处 |
| TEXT 上限 | 65535 字节;utf8mb4 中文 21845 个成功、21846 个报 1406 | 出处 |
| 非严格模式 | 不报 1406,改为 Warning 1265 并截断 | 出处 |
| 最后核对 | 2026-11-11 |
盈尺实测(测试库,非官方文档):2026-11-11 MySQL 8.4.7 测试库(自造 p 表,utf8mb4),字符与字节边界、多行 at row N、尾随空格、非严格模式截断的逐条输出。 本页第一段:测试库复现输出 →
字符还是字节:测试库实测边界
2026-11-11 在 box 本机测试库(MySQL 8.4.7,默认 sql_mode,utf8mb4,表和数据全部自造,非客户环境)建表 p(title VARCHAR(10), code CHAR(4), body TEXT, sku VARCHAR(10) CHARACTER SET latin1),逐条写入:
| 写入 | 结果 |
|---|---|
| title 写 11 个英文字母 | ERROR 1406 … for column 'title' at row 1 |
| title 写 10 个汉字 | 成功:CHAR_LENGTH=10,LENGTH=30 字节 |
| title 写 11 个汉字 | ERROR 1406 |
| code CHAR(4) 写 5 个字符 | ERROR 1406 … for column 'code' |
| body TEXT 写 REPEAT('中',21845) | 成功:LENGTH=65535 字节 |
| body TEXT 写 REPEAT('中',21846) | ERROR 1406 … for column 'body' |
| latin1 列写 emoji | 不是 1406,而是 ERROR 1366 Incorrect string value: '\xF0\x9F\x98\x80' |
结论:VARCHAR 不用为中文乘以 3,按字符数定义就行;真正按字节卡上限的是 TEXT(以及行大小、索引前缀)。存长中文正文请用 MEDIUMTEXT。emoji 写不进是字符集问题,看 1366 速查页。
'at row N' 怎么定位,以及整条语句都没写进去
测试库 INSERT INTO p(id,title) VALUES (5,'ok'),(6,'ok'),(7,'this-is-too-long') 报 … at row 3:N 是本条语句 VALUES 里的第几行,不是表里的行号,也不是主键值。严格模式下 InnoDB 表整条语句回滚,前两行 'ok' 也没有写入。UPDATE 同样报 1406(at row 1)。
SELECT id, CHAR_LENGTH(title) AS chars, LENGTH(title) AS bytes
FROM p
WHERE CHAR_LENGTH(title) >= 10 -- 10 换成列定义长度
ORDER BY chars DESC
LIMIT 20;不报 1406 反而更危险:尾随空格、sql_mode=''、INSERT IGNORE
- 超出部分只是尾随空格:严格模式下写
'abcdefghij '不报错,SHOW WARNINGS是Note 1265 Data truncated for column 'title' at row 1,存进去的是[abcdefghij]。 - sql_mode='':同样写 11 个字母不报错,只给
Warning 1265,数据被截成abcdefghij。 - INSERT IGNORE:严格模式下也会把 1406 降级为 Warning 1265 并截断。
如果有人为了「消除 1406」去掉了 STRICT_TRANS_TABLES,订单号、SKU、地址这类字段会被悄悄截断,事后对账才发现。先查 SELECT @@GLOBAL.sql_mode, @@SESSION.sql_mode; 确认严格模式还在。(Server SQL Modes)
怎么改:放宽列,而不是放宽模式
- 测试库
ALTER TABLE p MODIFY title VARCHAR(50)后原语句成功。生产上加宽 VARCHAR 是否能 INPLACE/INSTANT、会不会锁表,取决于长度跨越 255 字节边界等条件,先看 Online DDL 与元数据锁实测。 - 应用侧在写库前按 字符数 校验,与列定义保持一致;接口文档写清长度单位。
- 导入外部数据(亚马逊报表、ERP 导出)前,先在临时表用
MAX(CHAR_LENGTH(col))看源数据最大长度,再定列宽。
常见问题
mysql 1406 错误是什么意思?
1406(ER_DATA_TOO_LONG,SQLSTATE 22001)表示写入的值超过列定义长度。严格模式下整条语句失败;报错里的 at row N 是本条语句中的第 N 行。
VARCHAR(10) 能存几个汉字?
10 个。VARCHAR 的长度单位是字符,测试库 utf8mb4 下 10 个汉字成功、占 30 字节,11 个报 1406。
TEXT 能存多少中文?
TEXT 上限 65535 字节,utf8mb4 中文每字 3 字节,测试库 21845 个成功、21846 个报 1406。需要更长用 MEDIUMTEXT。
关掉严格模式就不报 1406 了,可以吗?
不建议。非严格模式和 INSERT IGNORE 会把超长数据静默截断,只留一条 Warning 1265。应该加宽列或在应用侧校验。
1406 和 1366 有什么区别?
1406 是长度超了;1366 是字符集存不下这个字符,例如 emoji 写入 latin1 或 utf8mb3 列。
下一步
价格以对应页面当前标价为准。
出处(最后核对 2026-11-11)
- MySQL 8.4 Error Reference:Server Error Message Reference
- MySQL 8.4 Reference Manual:String Data Type Storage Requirements
- MySQL 8.4 Reference Manual:Server SQL Modes(Strict SQL Mode)
本页摘录并解读上面列出的官方文档,不是官方页面;官方文档更新后以官方为准。除标明「盈尺实测」的一段外,其余内容都来自官方文档。