在BULK INSERT中确定导致“意外的文件结束”错误的ROW?

时间:2012-05-08 21:57:06

标签: sql sql-server sql-server-2008 bulkinsert

我正在进行批量插入:

DECLARE @row_terminator CHAR;
SET @row_terminator = CHAR(10); -- or char(10)

DECLARE @stmt NVARCHAR(2000);
SET @stmt = '
  BULK INSERT accn_errors
   FROM ''F:\FullUnzipped\accn_errors_201205080105.txt''
   WITH 
      (
        firstrow=2,
FIELDTERMINATOR = ''|''  ,
ROWS_PER_BATCH=10000
   ,ROWTERMINATOR='''+@row_terminator+'''
   )'
exec sp_executesql @stmt;

我收到以下错误:

Msg 4832, Level 16, State 1, Line 2
Bulk load: An unexpected end of file was encountered in the data file.
Msg 7399, Level 16, State 1, Line 2
The OLE DB provider "BULK" for linked server "(null)" reported an error. The provider did not give any information about the error.
Msg 7330, Level 16, State 2, Line 2
Cannot fetch a row from OLE DB provider "BULK" for linked server "(null)".

有没有办法知道这个错误发生在哪个ROW上?

我能够毫无问题地导入10,000,000行,并且在此之后发生错误

11 个答案:

答案 0 :(得分:46)

要找到麻烦的行,请使用errorfile说明符。

BULK INSERT myData
FROM 'C:\...\...\myData.csv'
WITH (
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n',
ERRORFILE = 'C:\...\...\myRubbishData.log' 
);

myRubbishData.log将包含违规行和随播文件 myRubbishData.log.txt将为您提供文件中的行号和偏移量。

伴随文件示例:

Row 3 File Offset 152 ErrorFile Offset 0 - HRESULT 0x80004005
Row 5 File Offset 268 ErrorFile Offset 60 - HRESULT 0x80004005
Row 7 File Offset 384 ErrorFile Offset 120 - HRESULT 0x80004005
Row 10 File Offset 600 ErrorFile Offset 180 - HRESULT 0x80004005
Row 12 File Offset 827 ErrorFile Offset 301 - HRESULT 0x80004005
Row 13 File Offset 942 ErrorFile Offset 416 - HRESULT 0x80004005

答案 1 :(得分:5)

有趣,有趣,有趣。我没有找到调试这些问题的好方法,所以我使用暴力。也就是说,FirstRow和LastRow选项非常有用。

从LastRow = 2开始并继续尝试。将结果加载到丢弃表中,您可以轻松截断。

而且,您还应该记住,第一行也可能导致您遇到问题。

答案 2 :(得分:3)

如果CHAR(10)是行终止符,我认为你不能像在BULK INSERT中那样把它放在引号中。但是,有一种无证的方式表明它:

ROWTERMINATOR = '0x0A'

答案 3 :(得分:3)

我有一个使用Bulk导入的csv文件

BULK INSERT [Dashboard].[dbo].[3G_Volume]
FROM 'C:\3G_Volume.csv'
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR = '","',
ROWTERMINATOR = '\n'
)
GO

通常我使用这个脚本并且它没有问题,但在罕见的情况下。

我遇到这个错误..

" OLE DB提供商" BULK"对于链接服务器"(null)"报告错误。提供商没有提供有关错误的任何信息。"

通常,当最后一行有空值(null)时会发生这种情况。

您需要在MS Access db中链接您的csv文件以检查数据。 (如果您的csv不超过140万行,您可以在excel中打开它)

由于我的数据大约是300万行,我需要使用访问数据库。

然后检查带有空格的最后一行的编号,并将空行数减去csv的总行数。

如果末尾有2个空白行,则总行数为30000005 脚本将变成这样......

BULK
INSERT [Dashboard].[dbo].[3G_Volume]
 FROM 'C:\3G_Volume.csv'
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR = '","',
ROWTERMINATOR = '\n',
Lastrow = 30000003
)
GO

...干杯 Mhelboy

答案 4 :(得分:2)

是的 - BULK INSERT会在其错误消息中提供更多细节,唯一的办法是使用强力方法,正如Gordon正确指出的那样。首先,根据您获得的错误,它要么不理解您的行终止符,要么在文件末尾缺少行终止符。使用FIRSTROW和LASTROW将有助于确定。

因此,您需要执行以下操作:

  1. 检查文件末尾是否有行终止符。如果没有,请将其中一个再试一次。还要确保最后一行包含所有必需的字段。它说'EOF',那就是你的问题。
  2. 你确定每行末尾有一个LF吗?尝试CR(\ n,0x0D)并查看是否有效。
  3. 仍然没有工作?尝试设置LASTROW = 2然后重试。然后尝试LASTROW = 3。如果文件中有三行以上且此步骤失败,则行终止符不起作用。

答案 5 :(得分:1)

我遇到了同样的问题。我编写了一个shell脚本来在Linux中创建.csv。我把这个.csv带到Windows并尝试批量加载数据。它没有“喜欢”逗号....不要问我为什么,但我在批量导入中更改为*作为分隔符并在我的.csv中执行查找并替换逗号*。 ..我改为〜作为分隔符,有效...标签也有效 - 它不喜欢逗号....希望这有助于某人。

答案 6 :(得分:0)

根据我的经验,这几乎总是由最后两行中的某些内容引起的。 tail导入文件,它仍然会给你失败。然后在全文编辑器中打开它,让您可以看到CR,LF和EOF等非打印字符。即使你不知道为什么,这应该使你能够使它变得有效。例如,BULK INSERT fails with row terminator on last row

答案 7 :(得分:0)

我通过将所有字段转换为字符串然后使用公共FIELDTERMINATOR解决了这个问题。这很有效:

BULK INSERT [dbo].[workingBulkInsert]  
FROM 'C:\Data\myfile.txt' WITH (
   ROWTERMINATOR = '\n', 
   FIELDTERMINATOR = ',' 
)

我的数据文件现在看起来像这样:

"01502","1470"
"01504","686"
"02167","882"
"106354","882"
"106355","784"
"106872","784"

第二个字段是十进制类型,没有双引号分隔符(如1470.00)。将两者格式化为字符串可消除错误。

答案 8 :(得分:0)

我有一个使用批量导入的CSV文件

您需要创建一个表,并且所有列应为可空值,并删除最后一行的空间,仅添加excel中可用的那些列。并且请不要创建主列,此过程不是Identity会自动增加,这就是创建错误的原因。

我已经完成了这样的批量插入:

CREATE TABLE [dbo].[Department](
    [Deptid] [bigint] IDENTITY(1,1) NOT NULL,
    [deptname] [nvarchar](max) NULL,
    [test] [nvarchar](max) NULL,
 CONSTRAINT [PK_Department] PRIMARY KEY CLUSTERED 
(
    [Deptid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
    ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

CREATE TABLE [dbo].[Table_Column](
    [column1] [nvarchar](max) NULL,
    [column2] [nvarchar](max) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

BULK INSERT Table_Column
FROM 'C:\Temp Data\bulkinsert1.csv'
WITH (
    FIELDTERMINATOR = ',',
    ROWTERMINATOR='\n' ,
    batchsize=300000 
);

insert into [dbo].[Department] 
select column1,column2 from Table_Column

答案 9 :(得分:-1)

如果我将所有字段转换为字符串然后使用公共字段分隔符,我就解决了这个问题。

答案 10 :(得分:-4)

生成此错误的行没有CHAR(10)终结符或具有不必要的空格