2012-07-02 105 views
3

我必須導入SAP未兌換的列表。這些報告看起來相當難看,並不適合自動化處理。但是沒有其他選擇。SQL SERVER批量插入忽略變形行

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 

不幸的是我收到follwing錯誤代碼:

數據是圍繞類似於下面的例子中減去和管道符號borderd
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)". 

拒絕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> 
+0

當我使用具有固定列寬的格式文件(CharFixed而不是CharTerm)時,我發現更好的支持。然後,您可以在where子句中檢查預期內容的某些列。但是,由於SAP會改變列的寬度,所以在我的用例中這不是一個選項。 – Toby

+0

很遺憾地看到,SQL Server似乎無法處理並非100%符合所提供格式的行。爲什麼不能忽略並記錄行,然後繼續而不是立即中止整個導入。更糟糕的是,一種錯誤文件被創建,並且只要存在一個錯誤文件(不會被用戶或外部程序刪除),就不能再啓動了!專業軟件不是那種奇怪的行爲嗎? – Toby

回答

5

BULK INSERT是出了名繁瑣的和無益的,當涉及到處理不符合規定的規格數據。

我沒有做很多與格式文件的工作,但你可能想一件事作爲替代使用BULK INSERT到文件的每一行放入臨時分段表單nvarchar(max)列考慮。

這可以讓你的數據進入SQL進一步檢查,然後你可以使用各種字符串操作函數將它分解成你想要最終插入的數據。

+0

感謝您的意見。其實我必須同意,SQL Server批量導入不是很複雜。而不僅僅是導入,而且數據轉換是殘酷的。這樣的商業產品真是太可惜了。 無論如何,用一個列臨時表的伎倆似乎是一種常見的做法。一位同事告訴過我同樣的事情。 雖然我很猶豫,但我擔心會對性能造成負面影響! – Toby

+0

我沒有很多像這樣預處理'BULK INSERT'的指標。如果它只是引起問題的文件末尾的一行,則可能需要考慮製作一個小型控制檯實用程序,以便在文件中查找最後一行並將其修剪掉。這樣你就可以將自己的東西包裝到自動上傳過程中。 – lyrisey

+0

這實際上是我最終做的。雖然不是很迷人!所有這些只是由於程序,SAP以及SQL Server的不足而造成的麻煩。我想知道哪種產品更差? (我個人會投票給SAP。) – Toby

0

我是在同樣的麻煩,但使用BCP命令行的問題解決了,它乾脆不走最後一排

+1

嗨,歡迎來到stackoverflow。請更多地描述答案。明確的答案將幫助人們理解你的意思,並增加選擇答案的機會 –

0

我有同樣的問題。我有一個115億行的文件,所以手動刪除最後一行不是一個選項,因爲我無法手動打開文件,因爲它太大了。

而不是使用BULK INSERT命令,我用BCP命令,它看起來像這樣: (打開在管理員DOS CMD然後寫)

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

這是大致相同的速度批量插入遠據我所知(只需12分鐘導入我的數據)。在查看活動監視器時,我可以看到一個批量插入,所以我猜測它在數據庫處於批量恢復模式時以相同的方式記錄。