SQLBulkcopy批量运行数据表

时间:2014-04-11 15:40:13

标签: c# sql sqlbulkcopy

目前我有一个大约1000万条记录的平面文件。

我首先读取文件并将列映射到数据表中。然后从Datatable使用SQLBulkCopy将其移动到数据库中。这是一个缓慢的过程,并且会耗费很多时间。

我想知道这个过程是否可以做得更好。

1)I.e。而不是将我的1000万条记录加载到数据表中,然后加载到数据库中。是否更好地加载"块" 100万进入数据表并在循环中处理它们直到所有处理?或者,如果任何人对如何改进这个过程有任何建议,我将不胜感激!

foreach (var line in File.ReadLines(fileLocation + @"\" + filename))
        {
            var dataColumns = line.Split('\t');
            var dr = dt.NewRow();

            for (var i = 0; i < dataColumns.Length; i++)
            {
                dr[i] = dataColumns[i].Trim().Length == 0 ? null : dataColumns[i];
            }

            dt.Rows.Add(dr);
        }

        using (var destinationConnection = new SqlConnection(Settings.Default.ConnectionString))
        {
            var tableName = filename.Substring(0, filename.IndexOf('.'));
            destinationConnection.Open();

            try
            {
                using (var createAndDropTableCommand = new SqlCommand("sp_DropAndCreateTable", destinationConnection))
                {
                    createAndDropTableCommand.CommandType = CommandType.StoredProcedure;
                    createAndDropTableCommand.Parameters.Add("@TableToCreate", SqlDbType.VarChar).Value = tableName;
                    createAndDropTableCommand.ExecuteNonQuery();
                }

                using (var bulkCopy = new SqlBulkCopy(destinationConnection))
                {
                    bulkCopy.DestinationTableName = "dbo." + tableName;
                    bulkCopy.BatchSize = 10000;
                    bulkCopy.ColumnMappings.Clear();
                    foreach (DataColumn col in dt.Columns)
                    {
                        bulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping(col.ColumnName, col.ColumnName));
                    }

                    bulkCopy.WriteToServer(dt);
                }
            }
            finally
            {
                destinationConnection.Close();
            }
        }

1 个答案:

答案 0 :(得分:0)

你肯定是在正确的轨道上 SQL批量复制应该能够在大约30秒内处理超过一百万条记录。我在dbsourcetools.codeplex.com中使用了DataBets和SQLBulkCopy

            System.Data.DataSet oDataSet = new System.Data.DataSet();
            oDataSet.ReadXmlSchema(strSchemaXml);
            oDataSet.ReadXml(strTableXml);

            if (oDataSet.Tables.Count > 0)
            {
                using (System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(oTargetDatabase.ConnectionString))
                {
                    conn.Open();
                    System.Data.SqlClient.SqlTransaction oTran = conn.BeginTransaction();

                    System.Data.SqlClient.SqlBulkCopy oSqlBulkCopy
                        = new System.Data.SqlClient.SqlBulkCopy(conn, System.Data.SqlClient.SqlBulkCopyOptions.KeepIdentity, oTran);
                    oSqlBulkCopy.BulkCopyTimeout = 600; 
                    oSqlBulkCopy.BatchSize = 1000;
                    oSqlBulkCopy.DestinationTableName = strFullyQualifiedTableName; 
                    oSqlBulkCopy.NotifyAfter = 10000;
                    oSqlBulkCopy.SqlRowsCopied += new System.Data.SqlClient.SqlRowsCopiedEventHandler(oSqlBulkCopy_SqlRowsCopied);
                    foreach (System.Data.DataColumn ocol in oDataSet.Tables[0].Columns)
                    {
                        oSqlBulkCopy.ColumnMappings.Add(ocol.ColumnName, ocol.ColumnName);
                    }

                    oSqlBulkCopy.WriteToServer(oDataSet.Tables[0]);
                    oTran.Commit();
                    conn.Close();
                }
                System.Console.WriteLine("Wrote : " + oDataSet.Tables[0].Rows.Count.ToString() + " records ");
            }