MySQL执行INSERT跨表导数据报#1364字段无默认值错误咨询
问题场景
你在执行跨表数据插入时,使用了如下语句:
INSERT INTO survols (Depart) SELECT Depart FROM survols_temp;
执行后MySQL返回如下报错:
#1364 - Field 'date_UTS' doesn't have a default value
其中date_UTS是源表survols_temp和目标表survols都存在的列,且测试全列插入时依然会触发相同报错。
插入场景下的字段默认值约束规则
这个报错是MySQL严格模式下的非空字段赋值规则导致的,规则逻辑非常明确:
- 执行INSERT操作时,所有未被显式指定写入值的列,MySQL会按固定优先级自动补值:
- 列配置了显式默认值的,直接填充配置的默认值
- 列是自增属性的,自动生成递增序列值填充
- 列允许为NULL且无默认值的,自动填充NULL
- 列同时满足设置了NOT NULL非空约束、没有配置默认值、不是自增列三个条件时,直接抛出1364报错,提示对应字段无默认值
你第一次执行的语句只指定了写入Depart这一列,其余列(包括date_UTS)都会走上述补值逻辑,而date_UTS刚好命中最后一条触发报错的条件,因此执行失败。
至于全列插入依然报错的问题,原因是INSERT ... SELECT语法做全列匹配时,不会自动按字段名对齐映射,只会严格按照SELECT返回的字段顺序,和目标表定义的列顺序一一对应赋值。出现相同报错就说明你写的SELECT字段列表漏了date_UTS,或者字段顺序和目标表定义不一致,导致date_UTS依然没有拿到显式传入的值,走到补值逻辑触发报错。
是否需要为每个字段都配置默认值
完全不需要,给所有字段强行加默认值是非常不合理的表设计,很容易产生不符合业务逻辑的脏数据。根据实际业务场景选择对应处理方式即可:
- 如果是部分列插入:要么给
date_UTS这类必须非空的列配置符合业务逻辑的默认值,要么在INSERT的字段列表里显式加上这些非空列,从源表查询对应值或者指定固定值写入,示例语句:
INSERT INTO survols (Depart, date_UTS) SELECT Depart, date_UTS FROM survols_temp;
- 如果是整表数据迁移:先执行
DESC survols;拿到目标表的列名、顺序定义,写SELECT语句时严格按照这个顺序把源表对应的列都列全,保证每个非空无默认值的列都有明确的取值来源,不要漏写字段。
如果排查时不确定字段约束,可以执行SHOW CREATE TABLE survols;直接查看目标表的完整建表语句,就能直观看到date_UTS等字段的非空、默认值配置是否符合预期。
内容的提问来源于stack exchange,提问作者JCRCAN
相关产品推荐
相关产品推荐

