SQL SERVER批量插入忽略变形行

时间:2012-07-02 10:54:50

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

我必须导入SAP不受限制的列表。这些报告看起来很丑陋,并不适合自动处理。但是没有其他选择。数据以减号和管道符号为边界,类似于以下示例:

02.07.2012
--------------------
Report name
--------------------
|Header1 |Header2  |
|Value 11|Value1 2 |
|Value 21|Value2 2 | 
--------------------

我使用格式文件和如下语句:

SELECT Header1, Header2
FROM  OPENROWSET(BULK  'report.txt',
FORMATFILE='formatfile_report.xml'  ,
errorfile='rejects.txt',
firstrOW = 2,
maxerrors = 100 ) as report

不幸的是我收到了以下错误代码:

Msg 4832, Level 16, State 1, Line 1
Bulk load: An unexpected end of file was encountered in the data file.
Msg 7399, Level 16, State 1, Line 1
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 1
Cannot fetch a row from OLE DB provider "BULK" for linked server "(null)".

rejects txt文件包含文件的最后一行,其中只包含一些缺陷。 rejects.txt.Error.Txt文件:

Row 21550 File Offset 3383848 ErrorFile Offset 0 - HRESULT 0x80004005

引发错误的罪魁祸首显然是最后一行不符合格式文件中声明的格式。然而,丑陋的标题不会引起太多问题(至少是最顶端的问题)。

虽然我定义了maxerror属性,但是一条变形线会杀死整个操作。如果我手动删除包含所有这些缺点的最后一行( - ),一切正常。由于进口应经常运行,特别是无人看管,额外的后处理不是严重的解决方案。

任何人都可以帮助我让sql server分别不那么挑剔和敏感。它记录了无法加载的行,但为什么会中止整个操作呢?并且在执行导致创建reject.txt的语句之后,在手动删除txt文件之前,不能执行其他(或相同)语句:

Msg 4861, Level 16, State 1, Line 1
Cannot bulk load because the file "rejects.txt" could not be opened. Operating system error code 80(The file exists.).
Msg 4861, Level 16, State 1, Line 1
Cannot bulk load because the file "rejects.txt.Error.Txt" could not be opened. Operating system error code 80(The file exists.).

我认为这是奇怪的行为。请帮我压制它。

编辑 - 关注: 这是我使用的格式文件:

<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <RECORD>
   <FIELD ID="EMPTY" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="100"/>
   <FIELD ID="HEADER1" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="100"/>
   <FIELD ID="HEADER2" xsi:type="CharTerm" TERMINATOR="|\r\n" MAX_LENGTH="100"/>
 </RECORD>
 <ROW>
   <COLUMN SOURCE="HEADER1" NAME="HEADER2" xsi:type="SQLNVARCHAR"/>
   <COLUMN SOURCE="HEADER2" NAME="HEADER2" xsi:type="SQLNVARCHAR"/>
 </ROW>
 </BCPFORMAT>

3 个答案:

答案 0 :(得分:5)

在处理不符合规格的数据时,

BULK INSERT非常繁琐且无益。

我还没有完成格式文件的大量工作,但您可能想要考虑作为替代品的一件事是使用BULK INSERT将文件的每一行放到一个临时的临时表中单nvarchar(max)列。

这使您可以将数据导入SQL以供进一步检查,然后您可以使用各种字符串操作函数将其分解为您要最终插入的数据。

答案 1 :(得分:0)

I was in the same trouble, but using bcp command line the problem was solved, its simply dont take the last row

答案 2 :(得分:0)

我遇到了同样的问题。我有一个包含115亿行的文件,因此手动删除最后一行不是一个选项,因为我甚至无法手动打开文件,因为它太大了。

我没有使用BULK INSERT命令,而是使用了bcp命令,它看起来像这样: (在管理员中打开DOS cmd然后写入)

bcp DatabaseName.dbo.TableNameToInsertIn in C:\Documents\FileNameToImport.dat -S ServerName -U UserName -P PassWord

据我所知,它与批量插入的速度大致相同(只需要12分钟即可导入我的数据)。在查看活动监视器时,我可以看到批量插入,所以我猜它在数据库处于批量恢复模式时以相同的方式记录。