2013-06-03 36 views
1

我讀到使用SqlBulkCopy和方式,它可以減少使用時間量插入大量行,當我的情況是:我有一個Excel文件,希望我把它轉換成一個dataTable然後我發送這個dataTable到一個存儲過程(希望我不能更改它的代碼),將數據表中的所有行插入到數據庫中的sql表中降低INSERT語句的時間與大量數據的時候

問題是我有10 000 50 000行插入是否有任何解決方法來減少存儲過程所花費的時間?

+2

尚不清楚在所有...你想用SqlBulkCopy的,或者你的SP,或BULK INSERT在你的SP?你可以改變你的SP的代碼,或者不要(我不明白'希望我不能改變它的代碼') –

+1

除非你可以改變存儲過程,否則你不能使用SqlBulkCopy,因爲存儲過程是這樣做的在這一刻。您將能夠減少的唯一方式是環境,即將恢復模式變爲簡單。你可以減少你的表的大小,而不是發送50000行一次發送1000說?因爲我不知道這個SP實際上做了什麼,所以很難給予更多的幫助。 – TheKingDave

+2

據我所知'SqlBulkCopy'不適用於存儲過程。所以如果你不需要SP,你可以用'SqlBulkCopy'快速插入50000行。它也支持'DataTable'作爲輸入。 [SqlBulkCopy.WriteToServer方法(數據表)](http://msdn.microsoft.com/en-us/library/ex21zs8x.aspx) –

回答

2

要做到這一點是使用SqlBulkCopy的將數據添加到一個臨時表中,然後喂這些數據到存儲過程的最好方法。你需要編寫一些SQL代碼來完成處理,但這樣做的性能好處應該是值得的。

如果您創建一個新的存儲過程,那麼你必須運行所有這些代碼的數據庫引擎中,所以你不會被來回切換應用程序和數據庫引擎之間的額外好處。

一些代碼:

var importData = new DataSet(); 
    xmlData.Position = 0; 
    importData.ReadXml(xmlData); 

    using (var connection = new SqlConnection(myConnectionString)) 
    { 
     connection.Open(); 
     using (var trans = connection.BeginTransaction()) 
     { 
     using (var sbc = new SqlBulkCopy(connection, SqlBulkCopyOptions.Default, trans) { DestinationTableName = myTableName }) 
     { 
      foreach (DataColumn col in importData.Tables[0].Columns) 
      { 
      sbc.ColumnMappings.Add(col.ColumnName, col.ColumnName); 
      } 

      sbc.WriteToServer(importData.Tables[0]); //table 0 is the main table in this dataset 

      // Now lets call the stored proc. 
      var cmd = new SqlCommand("ProcessDataImport", connection) 
       { 
       CommandType = CommandType.StoredProcedure 
       }; 
      cmd.CommandTimeout = 1200; 
      cmd.ExecuteNonQuery(); 

      trans.Commit(); 
     } 
     connection.Close(); 
     return null; 
     } 
    } 

哪裏XMLDATA與XML數據符合批量導入myTableName包含要導入到表中的數據流。請記住,在進行批量複製時,列名必須匹配100%。案例也很重要。

的PROC會是這個樣子:

CREATE PROCEDURE [ProcessDataImport] 
AS 
BEGIN 
    DECLARE @IMPORTCOL INT 

    WHILE EXISTS (SELECT X FROM TEMPTABLE) 
    BEGIN 
    SELECT @IMPORTCOL = (SELECT TOP 1 COLUMN1 FROM TEMPTABLE) 
    EXEC DOTHEIMPORT @IMPORTCOL 
    DELETE FROM TEMPTABLE WHERE COLUMN1 = @IMPORTCOL 
    END 
END 
+0

你能提供一個可用於閱讀的例子或鏈接嗎?請 – Sora

+0

我會用一些代碼更新答案。 – Graymatter

+0

什麼應該是DestinationTableName? bcs在我的情況下,我不知道什麼是表名它是一個存儲過程,它可以包含多個表 – Sora