我读到了SqlBulkCopy以及它可以减少插入大量行时使用的时间量的方式:我有一个excel文件希望我将它转换为dataTable然后我将此dataTable发送到存储过程(希望我无法更改其代码)将dataTable中的所有行插入数据库中的sql表
问题是我有10 000到5万行要插入是否有任何工作可以减少存储过程所花费的时间?答案 0 :(得分:2)
执行此操作的最佳方法是使用SqlBulkCopy将数据添加到临时表,然后将该数据提供给存储的proc。您需要编写一些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