bcp错误:[Microsoft] [SQL Server Native Client 10.0] 字符串数据,右侧截断。

21

我最近在使用bcp时遇到了一个错误。以下是错误信息:

SQLState = 22001, NativeError = 0 Error = [Microsoft][SQL Server Native Client 10.0]String data, right truncation

我试图将数据解压到一个没有任何约束条件且数据类型相对较大的分段表中。我有11个来自不同表格的文件正在进行bcp和压缩,其中只有一个文件在解压时出现错误。 这是我一直在使用的命令。最近(当我尝试复制当前WH并设置过程时),我一直在遇到问题。

bcp.exe employee_details in employee_details.dat -n -E -S "servername" -U sa -P "Password"

我已经尝试将命令更改为-C -T -S,当我手动给出格式时它可以工作。这是我需要加载到我的WH中的一个非常重要的大型数据包。
我不知道这里是否有格式文件。 需要任何帮助。

谢谢

Cinnamon girl.


你能更具体一些吗?"相当大"是什么意思?你能展示表定义的实际CREATE TABLE以及文件中几个较长行的样本吗? - Aaron Bertrand
很抱歉,亲爱的Aaron,我可能没有表达清楚。我的文件大小可能在1000 KB到800,000KB之间,具体取决于流量或高峰时间。我的表有一些示例列,如 epoch_time(bigint)、server_id(varchar)、uid_rl(int)、apl(int),它们是标识列,还有其他分布在 int 和 float 类型之间的列。谢谢,Cinnamon girl - cinnamon girl
我不是要求看整个文件,或者模糊的东西像 varchar - varchar(什么)?输入长什么样子?你给我们一个模糊的错误信息,表明你试图插入至少一个值太大了,但你不会告诉我们表定义或展示导致问题的数据?你希望我们如何帮助你?也许你可以打印出你的文件,把它放在飞镖板上,扔一支飞镖,它就会显示出引起问题的值?这就是你要求我们为你做的事情。 - Aaron Bertrand
你必须使用bcp吗?您可以尝试使用Import and Export Data(64位)(也称为DTS向导)吗? 您必须精确指定数据格式,就像SSIS一样,并且必须使用原始数据类型而不是SQL数据类型,但它的效果非常好,并且允许您预览数据的解释方式。 - Bacon Bits
确保模式/列匹配。您甚至可以考虑删除目标表,并使用来自源表的脚本重新创建它。 - jumxozizi
11个回答

24
我们在进行BCP时也遇到了相同的问题,结果发现是.dat文件中的换行符有问题。
使用Notepad++查看文件,并点击“显示所有字符”以查看换行符。
使用-r“\r\n”选项运行BCP会抛出以下错误,即下面的命令:
bcp dbo.Test in C:\Test.dat -c -t "|" -r "\r\n" -S "DBServerName" -T -E

"SQLState = 22001,NativeError = 0,错误 = [Microsoft][SQL Server Native Client 10.0]字符串数据,右侧截断"

使用-r"\n"或-r"\r"选项,BCP将文件中的所有行视为单个行,命令如下:

bcp dbo.Test in C:\Test.dat -c -t "|" -r "\n" -S "DBServerName" -T -E

当我们在BCP命令中使用十六进制值(0x0a)作为换行符时,问题得到了解决。

bcp dbo.Test in C:\Test.dat -c -t "|" -r "0x0a" -S "DBServerName" -T -E

1
我的CSV文件是在Linux/PHP中创建的,换行符是"LF",使用"-r "0x0a""对我有用! - Nick Rolando
@MayankJha 我的文件即使使用UNIX EOL字符也无法加载,但是使用十六进制值作为换行符却可以——太棒了。 - Ali
"-r "0x0a"起了作用,谢谢" - m0dest0
-r "0x0a"解决了问题,谢谢 - undefined

4

我也遇到了截断信息的问题。在搜索论坛并尝试建议的解决方案几个小时后,我终于让我的负载工作了。

截断消息的原因是我太天真了,认为在格式文件中放置列名实际上很重要。似乎前面的数字决定了数据加载的位置。

我的输入文件没有第三列的数据。这就是我的格式文件的样子。

... ","    1 Cust_Name       SQL_Latin1...
... ","    2 Cust_Ref        SQL_Latin1...
... ","    3 Cust_Amount     SQL_Latin1...
... "\r\n" 4 Cust_notes   SQL_Latin1...

我的输入文件长这样:

Jones,ABC123,200.67,New phone 
Smith,XYZ564,10.23,New SIM 

表格看起来像这样:
Cust_Name Varchar(20)
Cust_Ref  Varchar(10)
Cust_Type Varchar(3)
Cust_amount Decimal(10,2)
Cust_Notes Varchar (50)
Cust_Tel   Varchar(15)
Cust......

我曾以为在格式文件中给出列名后,数据会自动填入表格中对应的列。

然而事实并非如此,由于列号的重要性大于列名,因此列名只是噪音。

... ","    1 A       SQL_Latin1...
... ","    2 B       SQL_Latin1...
... ","    4 C       SQL_Latin1...
... "\r\n" 5 D       SQL_Latin1...

4
BCP 右侧截断错误是指当一列的数据过多无法适应它时发生的错误。这可能是由于格式文件(如果有使用)或定界符不正确造成的。行终止符(Windows 为 CRLF 或 '\r\n',UNIX 为 '\n')也可能导致此错误。例如,您的格式文件包含 Windows 的 CRLF 即 '\r\n' 作为行终止符,但文件中包含 '\n' 作为行尾。这意味着将整个文件放在 1 行(而不是 1 列)中,从而导致右侧截断错误。

我并不是很理解你的分析。但是,对于换行符的提及给予一个加1。在我的情况下,我们的数据中有换行符字符,这是BCP真的不喜欢的。 - Richard

3

对我们来说,问题出在我们试图上传的文件格式为Unicode而不是ANSI。

有一个-N开关,但我们的数据表中没有任何NVARCHAR数据。

我们只需将文件保存为ANSI格式即可解决问题,但如果你有NVARCHAR数据或者需要使用-N开关,请参考TechNet - 使用Unicode本地格式导入或导出数据


不错!我成功地使用保存为ANSI格式的csv文件进行了导入...但是在文件某些位置仍然出现了一些截断错误...而且在使用BCP时无法去除双引号封装...有什么想法吗? - Paulo Henrique
@PauloHenrique 抱歉,我没有解决方案。您可以尝试更改分隔符,然后在暂存表中处理该字段。最近,我只是将数据加载到 .Net DataSet 中,然后将其作为用户定义的表类型传递给存储过程,但这并不太灵活。当类型更改时,我还会对类型名称进行排序。虽然这更加复杂,但更容易进行故障排除。对于临时需求,我只需创建一个 XML 字符串,然后在存储过程中解析它,但如果存在大量数据转换,则有时很难进行故障排除。 - Charles Byrne

2
在我的情况下,问题是因为一个字段中写着 "|" = chr$(124),而分隔符在我的情况下是 "|" = chr$(179)。MS SQL 不能区分这两个字符。我消除了 chr$(124),然后通过BCP导入正常运行。

2
我知道这已经过时了 - 但是我刚刚遇到一个错误,发现我的一个数字字段的小数位比模式允许的要多。

0
晚了一些,但是:在我的情况下,我确切地得到了这个。
SQLState = 22001, NativeError = 0
Error = [Microsoft][ODBC Driver 11 for SQL Server]String data, right truncation

问题在于模式已更改。目标数据库有两个新字段。一旦我安装了先前的模式,导入就成功了。


0

经过花费4个小时,进行了大量的尝试和错误,我发现解决方案可能就像导入数据的表格一样简单,应该具有适合您要导入的文件的模式。 例如:在我的情况下,我正在将一个包含667,aaa,bbb的.csv文件导入到一个具有模式int(4),char(2),char(2)的表中,导致字符串数据,右截断。


1
请原谅我的天真,但是667,aa,bb怎么不符合int(4),char(2),char(2)的要求呢? - r2evans
1
抱歉,已更新帖子。 - Chandu Rajasagi

0

在Notepad++中打开文件。转到“视图”选项卡->显示符号->显示所有字符。我在.tsv文件中也遇到了同样的问题,一个制表符错位了。


0

我的bcp忽略了任何类似于\r、\n、\r\n、0x0d、0x0a、0x0d0x0a等的换行符。我找到的唯一解决方案是直接在bcp命令中包含“真正”的换行符。我认为这是有效的,因为csv文件是在与bcp运行的同一台服务器上生成的。当我手动将csv文件传输到mssql服务器时,0x0a也可以在BULK INSERT中使用。

请注意,nl1=^后面必须跟着两个新的空行。

my_script.bat:

@echo off
setlocal enableDelayedExpansion

set nl=^


set cmd=bcp db_name.db_schema.my_table in stats.csv -w -t, -r "!nl!" -S my_server -U my_username -P password123
!cmd!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接