SQL SERVER批量插入忽略变形行

Tob*_*oby 3 sql sql-server bulkinsert openrowset sql-server-2008

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

02.07.2012
--------------------
Report name
--------------------
|Header1 |Header2  |
|Value 11|Value1 2 |
|Value 21|Value2 2 | 
--------------------
Run Code Online (Sandbox Code Playgroud)

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

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

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

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)".
Run Code Online (Sandbox Code Playgroud)

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

Row 21550 File Offset 3383848 ErrorFile Offset 0 - HRESULT 0x80004005
Run Code Online (Sandbox Code Playgroud)

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

虽然我定义了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.).
Run Code Online (Sandbox Code Playgroud)

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

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

<?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>
Run Code Online (Sandbox Code Playgroud)

小智 5

BULK INSERT 在处理不符合规格的数据时,这是非常繁琐且无益的.

我没有对格式文件做过很多工作,但您可能想要考虑作为替代品的一件事是使用BULK INSERT将文件的每一行放到具有单列的临时登台表中nvarchar(max).

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