MySQL视图执行count(*)报Data too long for column错误求助
Data too long错误的问题 这事儿确实有点反直觉——一般我们默认ERROR 1406 (22001): Data too long只会在插入或更新数据时出现,但你在对视图dm.vSscore24执行count(*)时触发这个错误,核心原因其实是视图在执行查询时的动态计算过程中,某个字段的结果长度超出了它的定义限制,结合你的场景,重点就是那个pbs字段。
先明确你的场景细节:
- 操作:对包含多表关联、嵌套视图的
dm.vSscore24执行count(*) - 错误:
ERROR 1406 (22001): Data too long for column 'pbs' at row 1 - 数据库版本:MySQL 5.7.20-0ubuntu0.16.04.1-log(InnoDB 5.7.20)
可能的原因分析
视图本质是虚拟表,查询视图时MySQL会把视图的定义展开成实际的SQL执行。触发这个错误的常见情况有:
- 视图中
pbs字段是计算生成的:比如用CONCAT拼接多个字段、或者做了类型转换,计算后的结果长度超过了视图定义中该字段的声明长度(比如视图里把pbs定义为VARCHAR(50),但拼接后结果有60个字符)。 - 底层表的
pbs字段本身数据超标:之前修改数据时可能因为SQL_MODE没开启严格模式,超长数据被静默截断但没报错,现在视图查询时(尤其是嵌套视图的多层计算)触发了长度校验。 - 多表关联导致的字段值异常:关联逻辑让
pbs字段取到了来自其他表的超长值,超出了视图对该字段的长度限制。
排查与解决步骤
1. 先搞清楚视图里pbs字段的来源
执行这条SQL查看视图的完整定义:
SHOW CREATE VIEW dm.vSscore24;
重点看pbs字段是直接引用底层表的字段,还是通过函数(比如CONCAT、CAST)计算出来的。
2. 检查字段长度是否匹配
如果
pbs是直接引用底层表的字段:
先查底层表的字段定义:DESCRIBE 你的底层表名; -- 替换成实际的表名再查该字段的实际数据最大长度:
SELECT MAX(LENGTH(pbs)) FROM 你的底层表名;如果最大值超过了字段定义的长度,说明之前的数据写入时没触发错误(可能SQL_MODE没开严格模式),现在视图查询时校验了长度。这种情况要么修改底层表字段的长度,要么清理超长数据。
如果
pbs是视图中计算生成的字段:
比如视图里有CONCAT(a.col1, b.col2) AS pbs,那计算后的总长度可能超过了视图里pbs的声明长度。解决方法:- 要么修改视图定义,把
pbs的类型调整为更长的(比如VARCHAR(255)甚至TEXT); - 要么在计算时加截断逻辑,比如
SUBSTRING(CONCAT(a.col1, b.col2), 1, 255) AS pbs。
- 要么修改视图定义,把
3. 检查SQL_MODE设置
执行这条SQL查看当前的SQL模式:
SELECT @@SQL_MODE;
如果结果里没有STRICT_TRANS_TABLES,说明之前写入数据时,MySQL允许超长数据被静默截断而不报错,但视图查询的计算过程可能触发了严格校验。可以考虑开启严格模式(修改my.cnf后重启),但要注意这会影响后续的数据写入(超长数据会直接报错)。
4. 临时验证问题点
你可以先跳过pbs字段执行count,确认是不是这个字段的问题:
SELECT COUNT(*) FROM (SELECT id, 其他字段 FROM dm.vSscore24) AS temp;
如果这条SQL能正常执行,那就100%确认是pbs字段的长度问题,再针对性处理即可。
内容的提问来源于stack exchange,提问作者João Pinela




