Windows下UTF-8 BOM格式CSV导入MariaDB首行首列冗余空格问题
UTF-8 BOM导致MySQL LOAD DATA首行字段前缀异常的问题排查与解决
问题场景
在Windows系统下使用MySQL的LOAD DATA命令导入UTF-8带BOM的CSV文件时,首行prod字段开头出现无法用普通空格替换的异常字符,其余数据导入均正常。
相关文件与代码
- 待导入CSV内容:
3K;Cartridge/CHRA/Core Assy;B9DC3A;96,11;1057,21;1371,48;36,21;1602,78;54357100500;328;;;53037100500;; 3K;Cartridge/CHRA/Core Assy;D6EC42;483,95;5323,45;5603,62;10,53;6548,67;13877100500;328;;;13877100500;; 3K;Cartridge/CHRA/Core Assy;D79352;132,45;1456,95;1831,50;31,99;2140,39;53037100501;328;;;53037100501;; 3K;Cartridge/CHRA/Core Assy;D79353;119,08;1309,88;1683,33;34,94;1967,23;53037100502;328;;;53037100502;; 3K;Cartridge/CHRA/Core Assy;D79354;164,09;1804,99;2299,99;33,80;2687,88;53037100503;328;;;53037100503;;
- 数据库表结构:
CREATE DATABASE db DEFAULT CHARACTER SET 'utf8' DEFAULT COLLATE 'utf8_general_ci'; CREATE TABLE IF NOT EXISTS oo ( id INT NOT NULL AUTO_INCREMENT, iid VARCHAR(255), prod VARCHAR(255), grp VARCHAR(255), al VARCHAR(255), ap VARCHAR(255), mp VARCHAR(255), ic VARCHAR(255), td VARCHAR(255), td_p INT, add_inf TEXT, INDEX( iid ), PRIMARY KEY( id ) );
- 使用的导入命令:
LOAD DATA LOCAL INFILE 'd:\\inn.csv' INTO TABLE `oo` CHARACTER SET 'utf8' FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '\"' ESCAPED BY '\"' LINES TERMINATED BY '\r\n' ( prod, grp, ic, @dummy, @dummy, @dummy, @dummy, @dummy, @td, td_p, @dummy, @dummy, al, ap, mp, @add1, @add2 ) SET td = @td, iid = concat( @td, '--', @prod ), add_inf = concat( @add1, @add2 );
问题原因
你遇到的“额外空格”并非普通空格,而是**UTF-8 BOM(字节顺序标记)**的三个字节(EF BB BF)。Windows系统下保存的UTF-8文件常自动添加BOM,但MySQL的LOAD DATA命令默认不会识别并移除BOM,导致这三个字节被当作首行第一个字段(prod)的前缀内容。由于它不是普通空格字符,使用REPLACE(@prod, ' ', '')自然无法去除。
解决办法
方案1:移除CSV文件的BOM(最彻底)
用专业文本编辑器(如Notepad++)打开CSV文件:- 点击编码菜单,选择「UTF-8 无BOM」
- 重新保存文件后再执行导入命令
方案2:在
LOAD DATA命令中处理BOM
无需修改源文件,直接在SET子句中添加BOM移除逻辑:LOAD DATA LOCAL INFILE 'd:\\inn.csv' INTO TABLE `oo` CHARACTER SET 'utf8' FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '\"' ESCAPED BY '\"' LINES TERMINATED BY '\r\n' ( @prod_raw, grp, ic, @dummy, @dummy, @dummy, @dummy, @dummy, @td, td_p, @dummy, @dummy, al, ap, mp, @add1, @add2 ) SET td = @td, prod = TRIM(BINARY '\xef\xbb\xbf' FROM @prod_raw), -- 精准移除BOM前缀 iid = concat( @td, '--', TRIM(BINARY '\xef\xbb\xbf' FROM @prod_raw) ), add_inf = concat( @add1, @add2 );这里将原来的
prod参数先存入临时变量@prod_raw,再用TRIM(BINARY '\xef\xbb\xbf' FROM ...)移除BOM字节。方案3:修改MySQL字符集配置(针对高版本)
如果使用MySQL 8.0及以上版本,可尝试将字符集指定为utf8mb4,部分场景下utf8mb4会自动处理BOM:LOAD DATA LOCAL INFILE 'd:\\inn.csv' INTO TABLE `oo` CHARACTER SET 'utf8mb4' -- 替换为utf8mb4 FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '\"' ESCAPED BY '\"' LINES TERMINATED BY '\r\n' ( prod, grp, ic, @dummy, @dummy, @dummy, @dummy, @dummy, @td, td_p, @dummy, @dummy, al, ap, mp, @add1, @add2 ) SET td = @td, iid = concat( @td, '--', @prod ), add_inf = concat( @add1, @add2 );
内容的提问来源于stack exchange,提问作者Slawowid
相关产品推荐
相关产品推荐

