簡體   English   中英

帶有DbDataReader的SqlBulkCopy的隨機行為

[英]Random behavior of SqlBulkCopy with DbDataReader

我當前正在編寫一個Asp.Net網站,該網站將上傳Excel文件並將其內容保存到SQL Server數據庫,並使用SqlBulkCopyDbDataReader進行此操作。

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會引發錯誤消息

“ Net”列不允許使用DBNull.Value。

事實並非如此。

但是,我的任何測試文件中都沒有Null。 其中有些失敗,有些可行。 它抱怨不同文件的列不同,但特定文件總是相同。

這是到目前為止我嘗試過的,並得出以下結論:

  1. 我將測試文件之一分成較小的部分,以嘗試識別數據錯誤。 較小的文件有效,因此我在原始文件中添加了越來越多的行,直到它損壞為止。 這將指示數據錯誤。 但是該行看起來不錯,並將其放在另一個可以工作的文件中。 然后將其移至倒數第二行,並刪除(現在)最后一行,它可以工作。 所以不是數據錯誤。

  2. 下一個想法是大小,當逐行添加直到行破裂時,出現可重復的行為-添加行和文件將不起作用。 刪除它,它可以工作。 魔術數字是13959行。 但是,一些正常工作的文件更大,因此我嘗試了另一個不工作的文件。 它顯示出完全相同的行為,但在14259行后破裂。 因此,雖然確實顯示了與尺寸有關的問題,但不是尺寸問題。 可重復,但對於不同的文件則不同。 而且-再一次-其他更大的文件也可以工作。

  3. 嘗試了SqlBulkCopy的各種超時和批量大小,但沒有任何運氣。

  4. 在excel 12、8上使用或不使用XML,HDR等對各種ADODB提供程序字符串進行了嘗試。

  5. 嘗試了三種不同的ACE驅動程序包(我正在運行64位Windows 10和64位Office 2010,因此應該有一個正確的選項,但是我讀到它存在一些問題,因此我也嘗試了Office 2007和32位)。 沒變。

  6. 添加了一段代碼,以實際讀取DataReader逐行讀取並查找Net = Nothing的行,以防出現讀取Excel而不是寫入數據庫的問題。 找不到任何東西。

  7. 在這里添加了一個問題,希望任何人都可以提供一些進一步的東西進行測試或對正在發生的事情有一些見解。 對我沒有意義...

謝謝

更新:

嘗試按照Gordon的建議在Excel select中添加所有列名稱(謝謝!)。 沒用

還嘗試為兩個參數添加一個“其中xx不為null的地方”,這會引起Bruce建議的不同文件中的錯誤(謝謝!)。 這樣可以消除錯誤,並上傳文件。 但是,僅導入文件的一部分。 對於一個文件,文件14088的記錄被上傳了30727,對於另一個文件14305的文件被上傳了81195。

記錄數量仍然沒有邏輯,Excel中仍然沒有明顯的數據錯誤或空值。 沒道理...

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

上載時,也只是在事件日志中找到了它。 不知道是否相關。

“ SQL Server進程內存的重要部分已被調出。這可能會導致性能下降。持續時間:0秒。工作集(KB):141460,已提交(KB):393412,內存利用率:35 %%。”

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

SELECT Id, CustomerId, Net FROM [Sheet1$]

在Excel中從外觀上看為空的行仍可以被Excel視為“已填充”的行。 如果您按ctrl-end,通常可以看到這些內容。 您最終將在工作表中的行比預期的位置更遠。 空列的工作方式相同。 通常,您可以通過移動選擇行標題並右鍵單擊並選擇刪除選項來刪除這些行。

為什么不嘗試瘋狂處理並將查詢更改為

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

我認為這是使用Jet驅動程序排除null的正確語法。

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

原來它與BulkCopy或數據庫無關。 正是Excel的讀取步履蹣跚。

經過更多調試和臨時代碼后,我發現只有大約14'記錄從Excel被讀入DataReader。

在連接字符串中添加了IMEX = 1,並清除了一些雙引號和三引號,並且可以正常使用。 Ace連接字符串現在為:

“ Provider = Microsoft.ACE.OLEDB.12.0;數據源= {0};擴展屬性=”“ Excel 8.0; HDR = YES; IMEX = 1;”“”,路徑)

感謝您的所有投入。 不勝感激。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM