Navicat导入界面不支持字符串到NULL的字段级映射,需通过LOAD DATA INFILE+SET子句或先导入临时表再用UPDATE+CASE/NULLIF清洗实现。

不能在Navicat导入界面直接配置“把某字符串自动转为NULL”——它没有字段级值映射规则功能。必须靠预处理或SQL层拦截。
Navicat 导入时无法设置字符串→NULL 映射规则
Navicat 的 Excel/TXT/CSV 导入向导只支持列类型映射、编码选择、空值识别(如把空白单元格当 NULL),但不支持正则替换、条件转换或自定义字符串到 NULL 的映射。比如你希望把源数据里的 "N/A"、"NULL"、"unknown" 全部转成数据库 NULL,导入向导里找不到对应开关。
常见错误操作:在“空字符串处理”里勾选“将空字符串转为 NULL”,但这只对真正为空(长度为 0)的单元格生效,对含字符的标记串完全无效。
可行方案:用 LOAD DATA INFILE + SET 子句(MySQL)
如果你用的是 MySQL,且有文件系统访问权限(即 Navicat 连接的是本地或可读取服务器路径的 MySQL),可在 Navicat 中执行带 SET 的 LOAD DATA INFILE 语句,实现字段级条件赋值:
-
SET子句允许你在加载每行时,用CASE或函数动态计算目标字段值 - 例如,把 CSV 中第 3 列(假设是
status)中值为"N/A"的转为NULL,其余保留原值:
LOAD DATA INFILE '/path/to/data.csv'
INTO TABLE users
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS
(@col1, @col2, @col3, @col4)
SET name = @col1,
email = @col2,
status = CASE WHEN @col3 = 'N/A' THEN NULL ELSE @col3 END,
created_at = STR_TO_DATE(@col4, '%Y-%m-%d');
注意:@colX 是用户变量,需与 CSV 列顺序一致;STR_TO_DATE 等函数可同步做类型转换。
更通用方案:先导入临时表,再用 UPDATE+CASE 清洗
这是兼容所有数据库(MySQL/PostgreSQL)且最可控的方式。分三步走:
- 新建一张结构相同但所有字段都允许
NULL的临时表(如users_import),用 Navicat 正常导入原始数据(不加任何转换) - 执行清洗 SQL,把标记字符串批量转为
NULL:
UPDATE users_import
SET status = NULL
WHERE status IN ('N/A', 'NULL', 'unknown', '');
- 再用
INSERT INTO ... SELECT把清洗后的数据转入正式表(可配合IFNULL()或COALESCE()做兜底)
这个流程的关键点在于:Navicat 不参与值逻辑转换,只负责“无损搬运”,真正的业务规则由 SQL 承担。 避免了导入中途失败、部分行被跳过等不可控问题。
PostgreSQL 用户注意:regexp_replace 不适用此场景
别试图在导入时用 regexp_replace() 替换字符串为 NULL——该函数返回字符串,不是 NULL。想得到 NULL,必须显式写 CASE WHEN ... THEN NULL 或用 NULLIF(col, 'N/A'):
UPDATE users_import SET status = NULLIF(status, 'N/A');
NULLIF(a,b) 是 PostgreSQL 标准函数:当 a = b 时返回 NULL,否则返回 a。比写一长串 CASE 更简洁,但只支持单值匹配。
真正容易被忽略的是:**所有这类转换都必须在数据进入主表前完成,一旦 NULL 被当作普通字符串存进去(比如存成文本 "NULL"),后续就很难靠索引高效识别和清理了。**


















