2016-07-26 14 views
0

我目前正在編寫一個Asp.Net站點,它將上傳Excel文件並將內容保存到SQL Server數據庫,並使用SqlBulkCopyDbDataReader來執行此操作。SqlBulkCopy與DbDataReader的隨機行爲

Excel和數據庫表的列名稱完全一樣。

相關代碼(減少爲清楚起見數列映射)

' Connection String to Excel Workbook 
Dim excelConnectionString As String = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=Excel 8.0", path) 
Dim connection As New OleDbConnection() 
connection.ConnectionString = excelConnectionString 
Dim command As New OleDbCommand("select * from [Sheet1$]", connection) 

' Bulk Copy to SQL Server 
Dim bulkInsert As New SqlBulkCopy(sqlConnectionString) 
bulkInsert.DestinationTableName = "UploadedOrders" 
bulkInsert.BulkCopyTimeout = 0 
bulkInsert.BatchSize = 50 
bulkInsert.ColumnMappings.Add("Id", "Id") 
bulkInsert.ColumnMappings.Add("CustomerId", "CustomerId") 
bulkInsert.ColumnMappings.Add("Net", "Net") 
... rest of columns 

connection.Open() 
Dim dr As DbDataReader = command.ExecuteReader() 
bulkInsert.WriteToServer(dr) 

WriteToServer最後調用拋出一個錯誤,說

列「淨」不允許DBNull.Value。

它沒有。

但是在我的任何測試文件中沒有空值。其中一些失敗,一些有效。它抱怨不同文件的不同列,但對於特定文件總是相同的。

這是我迄今爲止嘗試和結論是:

  1. 我在試圖找出數據錯誤分裂的我的測試文件中的一個在更小的碎片。一個較小的文件可以工作,所以我在原始文件中添加了越來越多的行,直到它破裂爲止,並且它確實如此。這將表明數據錯誤。但該行看起來很好,並將其放入另一個文件中。並將其移動到倒數第二,並刪除(現在)最後一行,它的工作原理。所以不是數據錯誤。

  2. 接下來的想法是大小和逐行添加行直到它打破了有一個可重複的行爲 - 添加行和文件將無法正常工作。刪除它,它的作品。神奇的數字是13959行。但是一些正在工作的文件更大,所以我嘗試了另一個無法使用的文件。它顯示了完全相同的行爲,但是在14259行之後破壞了。所以不是尺寸問題,儘管它確實顯示了與尺寸相關的問題。可重複,但對於不同的文件不同。而且 - 再一次 - 其他更大的文件可以工作。

  3. 試過了SqlBulkCopy的各種超時和bulksizes沒有運氣。

  4. 用excel 12,8試過各種ADODB提供程序字符串,無論是否帶有XML,HDR等都沒有變化。

  5. 嘗試了三種不同的ACE驅動程序包(我正在運行64位Windows 10和Office 2010 64位,所以應該有一個正確的,但我讀過它有一些問題,所以我嘗試了Office 2007和32位也)。不用找了。

  6. 添加了一段代碼,用於實際通過DataReader逐行讀取並查找具有Net = Nothing的行,以防讀取Excel而不是寫入數據庫。找不到任何。

  7. 在這裏增加了一個問題,希望任何人都可以提供一些更多的東西來測試或對發生的事情進行一些分析。對我來說沒有意義....

感謝

UPDATE:

嘗試添加在Excel中選擇所有列名戈登的建議(感謝!)。沒有工作。

還嘗試添加一個「其中xx不爲空」的幾個參數,這些參數在Bruce建議的不同文件中拋出錯誤(謝謝!)。這會導致錯誤消失並上傳文件。但是隻有一部分文件被導入。對於一個文件,在文件中上傳了30727個記錄,而另一個文件上傳了81195個記錄。

仍然沒有邏輯的記錄數量,在Excel中仍然沒有明顯的數據錯誤或空值。它沒有任何意義...

而且仍然不確定在從Excel讀取或插入數據庫時​​是否發生錯誤。

剛剛在事件日誌中發現了這一點,當做一個上傳。不知道它是否相關。 (KB):141460,已提交(KB):393412,內存使用率:35(可能爲英文頁面)(可能爲英文頁面) %%「。

回答

0

您是否嘗試過在SQL語句中指定列名?

SELECT Id, CustomerId, Net FROM [Sheet1$] 
+0

試過了。沒有好轉。 – AJ17

+0

嘗試增加BatchSize = 1000 –

0

在Excel中視覺上看起來空白的行仍然可以被Excel視爲「已填充」的行。如果你點擊ctrl-end,你通常可以看到這些。你會在表單的最後一行比你預期的更遠。空的列以相同的方式工作。通常可以通過選擇行標題並右鍵單擊並選擇刪除選項來刪除這些行。

爲什麼不嘗試用瘋狂去和改變你的查詢

select * from [Sheet1$] where Net IS NOT NULL; 

我認爲這是與噴氣司機排除空值正確的語法。

0

好的,所以我找到了問題和解決方案。

原來它與BulkCopy或數據庫沒有關係。這是從Excel讀取的動搖。

經過一些更多的調試和臨時代碼後,我發現只有一些14'的記錄從Excel讀取到DataReader中。

將IMEX = 1添加到連接字符串,並清理了一些雙+三重引號,它的工作原理。 Ace連接字符串現在是:

「Provider = Microsoft.ACE.OLEDB.12.0; Data Source = {0}; Extended Properties =」「Excel 8.0; HDR = YES; IMEX = 1;」「」,path)

感謝您的所有意見。不勝感激。