我有製表符分隔的文本文件。文件大約100MB。我想將這個文件中的數據存儲到SQL服務器表中。當存儲在sql server中時,該文件包含100萬條記錄。達到此目的的最佳方法是什麼?使用c分隔文本文件在SQL Server表中批量插入數據#
我可以在c#中創建momory數據表,然後上傳到sql服務器,但在這種情況下,它會加載整個100 MB文件到內存。如果文件大小變大怎麼辦?
我有製表符分隔的文本文件。文件大約100MB。我想將這個文件中的數據存儲到SQL服務器表中。當存儲在sql server中時,該文件包含100萬條記錄。達到此目的的最佳方法是什麼?使用c分隔文本文件在SQL Server表中批量插入數據#
我可以在c#中創建momory數據表,然後上傳到sql服務器,但在這種情況下,它會加載整個100 MB文件到內存。如果文件大小變大怎麼辦?
沒問題; CsvReader
將處理大多數分隔文本格式,並實現IDataReader
,因此可用於提供SqlBulkCopy
。例如:
using (var file = new StreamReader(path))
using (var csv = new CsvReader(file, true)) // true = first row is headers
using (var bcp = new SqlBulkCopy(connectionString))
{
bcp.DestinationTableName = "Foo";
bcp.WriteToServer(csv);
}
注意CsvReader
有很多的選擇更多更微妙的文件處理(指定分隔符規則等)。 SqlBulkCopy
是高性能批量加載API - 非常高效。這是一個流式讀寫器API;它不會立即加載所有的數據到內存中。
的問題。這是由某人開發的,並在MIT開放源代碼許可下。我正在尋找的是使用微軟提供的SDK來實現相同目標的最佳方式。無需額外的許可證。 – 2012-08-07 06:52:47
@SamirLakhani MIT許可證非常開放,並允許您免費使用代碼的許可證,前提是您在發佈的作品中包含其許可證:http://en.wikipedia.org/wiki/MIT_License – Cocowalla 2012-08-07 06:56:56
您應仔細閱讀文件中的行由行,所以你不必整行加載到內存:
using (var file = System.IO.File.OpenText(filename))
{
while (!file.EndOfStream)
{
string line = file.ReadLine();
// TODO: Do your INSERT here
}
}
*更新*
「這將使100萬個單獨的插入命令到SQL服務器有沒有什麼辦法使其成批量「
你可以使用參數化查詢,它仍然會發布1M插入,但仍然會很快。
或者,您可以使用SqlBulkCopy
,但如果您不想使用第三方庫,那將會相當困難。如果你是更適合的MS許可,您可以使用LINQ Entity Data Reader(下發布的MS-PL許可證),它提供了AsDataReader
擴展方法:
void MyInsertMethod()
{
using (var bulk = new SqlBulkCopy("MyConnectionString"))
{
bulk.DestinationTableName = "MyTableName";
bulk.WriteToServer(GetRows().AsDataReader());
}
}
class MyType
{
public string A { get; set; }
public string B { get; set; }
}
IEnumerable<MyType> GetRows()
{
using (var file = System.IO.File.OpenText("MyTextFile"))
{
while (!file.EndOfStream)
{
var splitLine = file.ReadLine().Split(',');
yield return new MyType() { A = splitLine[0], B = splitLine[1] };
}
}
}
如果你不想使用MS許可的代碼你也可以自己實現IDataReader
,但那將是一個PITA。請注意,上述的CSV處理(Split(',')
)完全沒有問題,並且表中的列名必須與MyType
上的屬性名相同。 TBH,我建議你和Marc一起回答這個問題
@pst I有人認爲海報知道如何做到這一點從 – Cocowalla 2012-08-07 06:43:19
這個問題的措辭這將使100萬個單獨的插入命令到SQL服務器。有沒有什麼辦法可以批量生產 – 2012-08-07 06:56:52
@Cocowalla爲什麼SqlBulkCopy很難沒有第三方庫?我正在做下面的方式,它看起來不錯: SqlBulkCopy bulkCopy = new SqlBulkCopy(...) bulkCopy.BulkCopyTimeout = 0; bulkCopy.DestinationTableName =「
爲什麼不只是'BULK INSERT'命令? – 2012-08-07 06:39:42
@pst如果我沒有弄錯,那就要求該文件與SQL Server位於同一臺服務器上,這可能是我知道的海報 – Cocowalla 2012-08-07 06:42:34