确定在大容量插入中导致“意外的文件末尾”错误的ROW?

问题描述 投票:22回答:11

我正在批量插入:

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)".

是否有办法知道此错误发生在哪一行?

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

sql sql-server sql-server-2008 bulkinsert
11个回答
48
投票

要找到麻烦的行,请使用错误文件说明符。

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
投票

如果我将所有字段都转换为字符串然后使用一个通用的fielddelimiter,我就解决了这个问题。


-4
投票

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


5
投票

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

从LastRow = 2开始,继续尝试。将结果加载到可立即截断的一次性表中。

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


3
投票

如果CHAR(10)是行终止符,我认为您不能像在BULK INSERT中那样将其放在引号中。不过,有一种未记录的方式来表明它:

ROWTERMINATOR = '0x0A'

3
投票

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

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

通常,我使用此脚本,但在极少数情况下,它没有问题。

我遇到此错误。

“链接服务器“(null)”的OLE DB提供程序“ BULK”报告了错误。提供程序未提供有关该错误的任何信息。”

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

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

因为我的数据大约有300万行,所以我需要使用Access db。

然后检查最后一行的空格,并将空行的数量减去csv的总行数。

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

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

欢呼...Mhelboy


2
投票

[是的-BULK INSERT会在错误消息中做更多细节,而唯一的解决方法是使用蛮力方法,正如Gordon正确指出的那样。但是,首先,根据您得到的错误,可能是您不了解行终止符,或者文件末尾缺少行终止符。使用FIRSTROW和LASTROW将有助于确定这一点。

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

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

1
投票

我遇到了同样的问题。我写了一个Shell脚本在Linux中创建一个.csv。我将此.csv带到Windows,并尝试批量加载数据。它不“喜欢”逗号...。不要问我为什么,但是我在批量导入中改为使用*作为分隔符,并在有效的.csv ..中执行查找并用*替换逗号。 ..我改成了〜作为定界符,它起作用了...选项卡也起作用了-它不喜欢逗号。...希望这对某人有所帮助。


0
投票

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


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)。将两者都格式化为字符串可以消除该错误。


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
© www.soinside.com 2019 - 2024. All rights reserved.