使用BCP迁移SQL Server数据,OPENROWSET读取BCP文件报错求助
解决BCP导出后OPENROWSET批量加载列过长的问题
你遇到的这个"The bulk load failed. The column is too..."错误,在使用BCP本地类型导出(-N参数)再通过OPENROWSET加载时很常见,主要是因为-N生成的格式文件没有准确匹配目标表的列长度定义,尤其是变长字符类型(varchar/nvarchar)的字段。下面给你几个可行的解决办法:
方法1:改用字符格式导出(最省心的方案)
放弃-N参数,改用-c(针对非Unicode字符)或-w(针对Unicode字符)导出数据和生成格式文件,这样格式文件会明确记录每列的最大长度,从根源避免长度不匹配问题:
非Unicode表(用-c参数)
- 导出数据命令:
bcp database.TableName OUT c:\data\bcp\TableName.bcp -T -c -S SQLINSTANCE - 生成格式文件命令:
bcp database.TableName format nul -f c:\data\bcp\TableName.fmt -T -c
Unicode表(用-w参数)
如果你的表包含中文、特殊符号等Unicode字符,换成-w:
- 导出数据命令:
bcp database.TableName OUT c:\data\bcp\TableName.bcp -T -w -S SQLINSTANCE - 生成格式文件命令:
bcp database.TableName format nul -f c:\data\bcp\TableName.fmt -T -w
重新导出后再执行你的OPENROWSET语句,大概率就能正常加载了。
方法2:手动修正格式文件(适合坚持用-N导出的场景)
如果你必须用-N参数导出,那需要手动编辑生成的.fmt文件,调整报错列的长度值:
- 打开
TableName.fmt文件,找到报错对应的列行(格式文件每行对应一列) - 找到该行的第6个字段(代表列长度):
- 对于
varchar(n)类型,把数值改成n - 对于
nvarchar(n)类型,把数值改成n*2(因为nvarchar是双字节存储)
- 对于
- 保存格式文件后,重新执行OPENROWSET加载语句
举个例子:如果目标表有个nvarchar(255)的列,格式文件里对应的长度可能是默认的小数值,你要改成510(255*2)。
方法3:换用BULK INSERT命令加载
有时候BULK INSERT对格式文件的兼容性比OPENROWSET更好,你可以试试这个命令:
BULK INSERT database.TableName FROM 'c:\data\bcp\TableName.bcp' WITH ( FORMATFILE = 'c:\data\bcp\TableName.fmt', ERRORFILE = 'c:\data\bcp\TableName_errors.log' -- 可选,用来记录加载失败的行 );
如果还是出现长度问题,同样可以参考方法1或方法2调整导出参数或格式文件。
额外注意事项
- 务必确认源表和目标表的结构完全一致:列顺序、数据类型、长度、精度、是否允许空值都要一一对应,哪怕细微差异都可能引发报错。
- 确保执行加载操作的SQL账号,以及SQL Server服务账号,都有读取BCP文件和格式文件所在路径的权限(很多时候权限问题会伪装成格式错误)。
- 如果是跨实例迁移,要保证目标服务器能访问到文件路径——要么把文件拷贝到目标服务器本地,要么放到双方都能访问的共享目录。
内容的提问来源于stack exchange,提问作者Peter Tirrell




