Navicat勾选“不是NULL”但未设默认值会生成仅含NOT NULL的ALTER语句,导致ERROR 1138报错;必须先UPDATE清理NULL值,再同步勾选“不是NULL”并清空“默认”栏(触发生成NOT NULL DEFAULT '')。
改字段 NOT NULL 时,Navicat 默认不保留原有约束
直接在“设计表”里勾选“不是 null”,但没手动填默认值,navicat 会生成 modify column xxx varchar(50) not null——这语句在 mysql 中要求**所有现存行该字段都不能为 null**,否则执行失败,报错 error 1138: invalid use of null value。
常见翻车点:原字段是 VARCHAR(50) DEFAULT NULL,你只想加 NOT NULL,却忘了先清理数据。Navicat 不会自动帮你 UPDATE 现有 NULL 值,它只管发 ALTER。
- 必须先执行
UPDATE your_table SET your_column = '' WHERE your_column IS NULL(或设为合理默认值) - 再回到设计表界面,勾选“不是 NULL”,同时在“默认”栏填
''(空字符串)或具体值,不能留空 - 点击保存前,务必点“SQL 预览”,确认生成语句含
NOT NULL DEFAULT '',而不是只有NOT NULL
把默认值从 NULL 改成空字符串,两个设置缺一不可
只改“默认”栏填 '',但没勾选“不是 NULL”,生成的 SQL 是 DEFAULT '',字段仍允许插入 NULL;只勾选“不是 NULL”但“默认”栏为空,Navicat 会当它是显式 DEFAULT NULL,结果还是报错。
正确组合只有这一种:
- 勾选“不是 NULL”
- “默认”输入框完全清空(不填任何字符,包括空格)
此时 Navicat 才会生成 NOT NULL DEFAULT ''。如果填了 NULL 字样,它就真按字面意思写进 SQL,导致约束失效。
大表加 NOT NULL 字段,别信“一键保存”
对百万级以上数据的表,在设计表里新增一个 NOT NULL 字段并设默认值,Navicat 预览里看到的可能是 ADD COLUMN xxx INT NOT NULL DEFAULT 0。MySQL 5.7+ 虽支持在线 DDL,但前提是存储引擎为 InnoDB 且无外键/触发器干扰;一旦降级为 COPY 算法,整个过程锁表、卡死、拖慢线上服务。
- 稳妥做法:先
ADD COLUMN xxx INT NULL(无锁) - 再分批
UPDATE your_table SET xxx = 0 WHERE xxx IS NULL LIMIT 10000(避免长事务) - 最后
MODIFY COLUMN xxx INT NOT NULL(此时全表已无 NULL,安全)
Navicat 不会帮你拆解步骤,它只按界面配置一步到底。预览 SQL 是你唯一能提前识别风险的机会。
修改已有字段类型时,COMMENT 和 DEFAULT 极易丢失
在“设计表”里只改了长度,比如把 VARCHAR(50) 改成 VARCHAR(100),其他栏位不动,Navicat 默认生成 MODIFY COLUMN name VARCHAR(100)——原始的 NOT NULL、DEFAULT ''、COLUMN_COMMENT '用户名' 全部消失。
这不是 Bug,是 MySQL 的语法特性:MODIFY COLUMN 必须显式重申所有属性,否则视为“不保留”。所以每次改类型或长度,都得人工核对三件事:
- “不是 NULL”是否和原来一致(勾/不勾)
- “默认”栏是否重填(哪怕和原来一样)
- “注释”栏是否重输(界面不继承旧 COMMENT)
最省事的方式:右键表 → “修改表”,别双击进“设计表”。前者强制你逐字段确认,后者容易漏项。











