SQL Server 2016批量插入报错:格式化文件列数无效排查求助
嘿,我太懂你这个坑了!带双引号包裹字段的CSV/TSV文件用Bulk Insert导入时,最容易栽在格式化文件的配置上,尤其是那个"Invalid column number"报错,大概率是你的.fmt文件里的列定义、分隔符和实际数据不匹配。咱们一步步来搞定:
先明确核心问题:双引号的处理逻辑
你的数据是"NUMBER","字段2","字段3"这种格式,每个字段都被双引号包裹,字段之间是","(引号+逗号)分隔,行尾是"\r\n"(引号+换行)。你的格式化文件必须精准匹配这个规则,不然SQL Server就会把引号当成字段内容的一部分,或者错误识别列数。
给你一套可直接复用的示例
假设你的目标表结构是这样的:
CREATE TABLE YourTargetTable ( NumberCol VARCHAR(20), Field2 VARCHAR(50), Field3 VARCHAR(100) )
对应的格式化文件formatfile1.fmt应该这么写(注意版本号对应你的SQL Server版本,比如SQL Server 2019是15.0,2016是13.0,别写错):
15.0 3 1 SQLCHAR 0 20 '","' 1 NumberCol SQL_Latin1_General_CP1_CI_AS 2 SQLCHAR 0 50 '","' 2 Field2 SQL_Latin1_General_CP1_CI_AS 3 SQLCHAR 0 100 '"\r\n' 3 Field3 SQL_Latin1_General_CP1_CI_AS
我给你拆解下关键部分:
- 第一行
15.0:SQL Server版本号,必须和你用的版本对应,错了会触发奇怪的错误 - 第二行
3:数据文件的列数,要和目标表列数完全一致 - 每一行的字段终止符:前两列用
'","'(匹配"字段1","字段2"的分隔),最后一列用'"\r\n'(匹配最后一个字段的"字段3"+换行) - 字段长度设得比实际可能的最大值大一点,避免截断报错
正确的Bulk Insert语句
如果你的数据文件第一行是表头(比如"NUMBER","字段2","字段3"),记得加上FIRSTROW=2跳过表头:
BULK INSERT YourTargetTable FROM '\\server\Data\Transfer\your_data_file.txt' WITH ( FORMATFILE = '\\server\Data\Transfer\formatfile1.fmt', FIRSTROW = 2, -- 有表头就加,没有就去掉 CODEPAGE = '65001' -- 如果是UTF-8编码的文件,ANSI编码可以去掉这个参数 )
排查报错的额外技巧
如果还是报错,按这几步查:
- 检查数据文件有没有空行、格式异常的行(比如某一行少了一个字段)
- 确认格式化文件的版本号:可以用
SELECT @@VERSION查看你的SQL Server版本,对应版本号参考:SQL Server 2012=11.0,2014=12.0,2016=13.0,2017=14.0,2019=15.0,2022=16.0 - 检查文件编码:如果是UTF-8带BOM,可能需要转成无BOM的UTF-8,或者调整CODEPAGE参数
- 把格式化文件里的字段长度调大,比如把
20改成50,避免因为字段内容过长导致的截断错误
内容的提问来源于stack exchange,提问作者NancyJoe
相关产品推荐
相关产品推荐

