1

我阅读了有关 SqlBulkCopy 以及它可以减少插入大量行时所用时间的方法我的场景是:我有一个 excel 文件希望将其转换为 dataTable 然后我将此 dataTable 发送到存储过程(希望我无法更改其代码)将 dataTable 中的所有行插入数据库中的 sql 表

问题是我有 10 000 到 50 000 行要插入是否有任何解决方法可以减少存储过程所花费的时间?

4

1 回答 1

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
于 2013-06-03T09:59:34.127 回答