执行 ALTER TABLE 后须立即运行 SHOW WARNINGS 查看警告,因该命令仅保留上一条语句的警告;MySQL 默认抑制低级别警告,需先设 SET SESSION log_warnings = 2(5.7+)才能显示完整警告。
ALTER TABLE 修改字段类型时如何看到警告信息
mysql 在执行 alter table ... modify 或 alter table ... change 时,如果类型转换存在隐式截断、精度丢失或字符集不兼容,**默认不会报错,但会生成警告(warnings)**。不主动查看,就等于“改了但没完全改对”。
关键操作只有两步:先开警告开关,再查警告内容。
-
SET sql_mode = 'STRICT_TRANS_TABLES';可让部分隐式转换直接报错(但不是所有场景都生效) - 更可靠的是:执行完
ALTER TABLE后,立刻执行SHOW WARNINGS; - 注意:
SHOW WARNINGS;只保留上一条语句的警告,执行其他语句后就会被覆盖
为什么 SHOW WARNINGS 经常显示空或只有 Note
常见现象是执行 ALTER TABLE t MODIFY c VARCHAR(10); 后运行 SHOW WARNINGS;,只看到 Note 级别提示,甚至什么都没有——这不代表安全,而是 MySQL 默认抑制了部分非致命警告。
- 必须先执行
SET SESSION log_warnings = 2;(MySQL 5.7+),否则低级别警告不记录 - MySQL 8.0 默认
log_warnings = 2,但旧版本或某些部署仍为 1 或 0 -
SHOW WARNINGS;不显示被截断的具体值,只提示“Data truncated for column 'c'”,需结合SELECT抽样验证
修改前用 SELECT + CAST 模拟转换效果
光看警告不够,因为警告只告诉你“可能出问题”,不告诉你“哪些行真出问题”。最稳妥的方式是提前模拟转换逻辑。
- 例如要把
INT改成TINYINT,先跑:SELECT id, c, CAST(c AS TINYINT) AS casted FROM t WHERE c != CAST(c AS TINYINT); - 若结果非空,说明已有数据超出新类型范围(
TINYINT是 -128~127) - 对字符串字段,用
LENGTH()和CHAR_LENGTH()检查是否超长,再用SUBSTR()看截断后是否可接受 - 注意:MySQL 的
CAST行为和ALTER ... MODIFY内部转换逻辑基本一致,可信度高
不同存储引擎对类型变更的警告粒度差异
InnoDB 和 MyISAM 在字段类型变更时的警告表现不一致,容易误判风险程度。
- InnoDB 对
VARCHAR → CHAR、TEXT → VARCHAR等操作通常只报Note,但实际可能触发表重建和锁表 - MyISAM 在
INT → TINYINT时可能直接报Warning并给出截断行号(极少),但多数情况也不报 - 真正影响大的是字符集变更(如
utf8mb4 → utf8),InnoDB 会明确警告 “Data will be truncated” 并列出列名 - 建议在测试库用
EXPLAIN FORMAT=JSON ALTER TABLE ...(MySQL 8.0.19+)看是否触发 ALGORITHM=COPY
警告本身只是线索,不是结论。真正危险的是那些没触发警告、但已静默丢数据的操作——比如把 VARCHAR(255) 改成 VARCHAR(50),而你忘了检查最长原始值长度。

















