MySQL导入空值报错主因是sql_mode含STRICT_TRANS_TABLES或STRICT_ALL_TABLES;临时会话级关闭用SET SESSION sql_mode='',导入后应立即SET SESSION sql_mode=DEFAULT恢复。
MySQL 导入空值被拒绝:sql_mode 里有 STRICT_TRANS_TABLES 或 STRICT_ALL_TABLES
mysql 默认开启严格模式,遇到 null 插入非空字段、类型不匹配、截断字符串等情况会直接报错,而不是转成默认值或静默处理。导入 csv/sql 文件时最常见的报错是:column 'xxx' cannot be null 或 data truncated for column 'yyy',根源往往就是这个模式。
临时关闭它最直接——但不是永久改配置文件,而是对当前会话生效,不影响其他连接:
-
SET SESSION sql_mode = '';—— 清空当前会话的 sql_mode(最彻底) -
SET SESSION sql_mode = (SELECT REPLACE(@@sql_mode,'STRICT_TRANS_TABLES',''));—— 只剔除 STRICT 相关项,保留其他如NO_ZERO_DATE - 导入完建议立刻恢复:
SET SESSION sql_mode = DEFAULT;,避免后续操作意外宽松
用 mysql 命令行导入时如何自动应用宽松模式
不能靠 source 命令前加 SET(它在事务外执行,不作用于后续 source),必须在连接时就指定初始语句:
- 命令行加
--init-command="SET SESSION sql_mode='';":
mysql -u root -p --init-command="SET SESSION sql_mode='';" mydb < data.sql
- 如果用
LOAD DATA INFILE,同样需先连上并手动执行SET SESSION,再运行该语句;mysql命令不支持对单条 SQL 文件内嵌 init-command - 注意:Windows 下双引号需转义或改用单引号,否则 shell 解析失败
sql_mode 改了但导入还是失败?检查这三点
宽松模式不是万能解药,下面这些情况即使关掉 STRICT 也拦不住:
- 目标字段是
NOT NULL且没设DEFAULT,插入NULL仍会报错 —— MySQL 5.7+ 即使非严格模式也不允许显式插 NULL 到 NOT NULL 字段(除非是空字符串或 0 等隐式转换) - CSV 中用了
\N表示 NULL,但LOAD DATA没加NULL TERMINATED BY '\N',它会当普通字符串处理,导致类型不匹配 - 表引擎是
MyISAM,它对 NULL 的容忍度比 InnoDB 高;但若字段定义为TINYINT NOT NULL,又试图插空字符串'',依然会转成 0 或报错,取决于其他 mode 设置
为什么不用永久修改 my.cnf?
因为风险太集中:所有应用连接都变宽松,可能掩盖业务逻辑缺陷,比如本该校验的空值被数据库默默吞掉,等查数据时才发现异常。线上库尤其要避免。
更稳妥的做法是:
- 只在导入脚本开头加
SET SESSION,且明确限定作用域(比如封装成 shell 函数) - 导入前用
SHOW CREATE TABLE看字段是否真需要允许 NULL,必要时ALTER TABLE ... MODIFY COLUMN ... NULL; - 真正该修复的是数据源 —— 比如导出时就补全默认值,或用
IFNULL()处理,而不是依赖数据库兜底
临时改 sql_mode 是把双刃剑,用完即弃;但字段定义和数据质量的问题,不会因为你关了一次 STRICT 就消失。










