使用SQL Bulkcopy解决大量数据写入的问题

本文介绍了两种提高数据库大批量数据处理效率的方法。首先,利用SQLBulkcopy进行数据导入,通过DataTable转换和映射优化,显著提升了数据插入速度。其次,展示了使用UpdateCommand参数更新数据的技巧,结合批处理和参数化查询,提高了更新操作的性能。这两种方法在处理大量数据时能有效减少资源消耗和时间成本。
摘要由CSDN通过智能技术生成

思路一:对于大批量数据采用ADO.Net或者linq to sql进行一条条执行会极大影响效率,而采用SQL Bulkcopy将整个对象集导入可以极大的缩短时间。代码执行分为如下三步。

1.使用代码对数据集进行预处理,比如修改数据或者过滤数据

2.将数据集转换为DataTable(自适应算法)

public static DataTable ToDataTable<T>(IEnumerable<T> collection)
        {
            var props = typeof(T).GetProperties();
            var dt = new DataTable();
            dt.Columns.AddRange(props.Select(p => new DataColumn(p.Name, p.PropertyType)).ToArray());
            if (collection.Count() > 0)
            {
                for (int i = 0; i < collection.Count(); i++)
                {
                    ArrayList tempList = new ArrayList();
                    foreach (PropertyInfo pi in props)
                    {
                        object obj = pi.GetValue(collection.ElementAt(i), null);
                        tempList.Add(obj);
                    }
                    object[] array = tempList.ToArray();
                    dt.LoadDataRow(array, true);
                }
            }
            return dt;
        }

3.使用SQL Bulkcopy将DataTable导入数据库

using System.Data;
using System.Data.SqlClient;
using System.Configuration;
        /// <summary>
        /// 批量导入
        /// </summary>
        /// <param name="connectionString">链接字符串</param>
        /// <param name="TableName">数据库名</param>
        /// <param name="dt">数据表</param>
        private void SqlBulkCopyByDatatable(string connectionString, string TableName, DataTable dt)
        {
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                using (SqlBulkCopy sqlbulkcopy = 
new SqlBulkCopy(connectionString, SqlBulkCopyOptions.UseInternalTransaction))
                {
                    try
                    {
                        sqlbulkcopy.DestinationTableName = TableName;
                        for (int i = 0; i < dt.Columns.Count; i++)
                        {
                            sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName);
                        }
                        sqlbulkcopy.WriteToServer(dt);
                    }
                    catch (System.Exception ex)
                    {
                        throw ex;
                    }
                }
            }
        }

如果数据结构不同的话则需要额外更改映射

        /// <summary>
        /// 不同表之间复制数据
        /// </summary>
        private static void PerformBulkCopyDifferentSchema()
        {
            string connectionString = @"连接字符串";
            DataTable sourceData = new DataTable();
            // 源 
            using (SqlConnection sourceConnection = new SqlConnection(connectionString))
            {
                SqlCommand myCommand = new SqlCommand("SELECT TOP 5 * FROM Products_Archive", sourceConnection);
                sourceConnection.Open();
                SqlDataReader reader = myCommand.ExecuteReader();

                // 目的
                using (SqlConnection destinationConnection = new SqlConnection(connectionString))
                {
                    // 打开连接
                    destinationConnection.Open();
                    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection.ConnectionString))
                    {
                        bulkCopy.ColumnMappings.Add("ProductID", "ProductID");
                        bulkCopy.ColumnMappings.Add("ProductName", "Name");
                        bulkCopy.ColumnMappings.Add("QuantityPerUnit", "Quantity");
                        bulkCopy.DestinationTableName = "Products_TopSelling";
                        bulkCopy.WriteToServer(reader);
                    }
                }
                reader.Close();
            }
        }

思路二:使用UpdateCommand参数将数据写入

DateTime begin = DateTime.Now;
            try
            {
                using (SqlConnection conn = new SqlConnection(connString))
                {
                    conn.Open();

                    SqlDataAdapter sd = new SqlDataAdapter();
                    sd.SelectCommand = new SqlCommand("select top 200 * from Mans", conn);

                    DataSet dataset = new DataSet();
                    sd.Fill(dataset);
                    Random r = new Random(1000);
                    sd.UpdateCommand = new SqlCommand("SQL 语句, conn);
                    sd.UpdateCommand.Parameters.Add("@参数", SqlDbType.VarChar, 200, "参数");
                    sd.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
                    sd.UpdateBatchSize = 0;


                    for (int count = 0; count < dt.Rows.Count - 1; count++)
                    {
                        for (int i = 0; i < 200; i++, count++)
                        {
                            if (count > dt.Rows.Count - 1) break;
                            dataset.Tables[0].Rows[i].BeginEdit(); 
                            dataset.Tables[0].Rows[i]["参数"] = dt.Rows[count][0];//源数据表对应的位置
                            dataset.Tables[0].Rows[i].EndEdit();//终止发生在该行的编辑。
                        }
                        //Update:为指定 System.Data.DataTable 中每个已插入、已更新或已删除的行调用相应的 INSERT、UPDATE 或 DELETE 语句。
                        sd.Update(dataset.Tables[0]);
                    }


                    dataset.Tables[0].Clear();
                    sd.Dispose();
                    dataset.Dispose();
                    conn.Close();

                }
            }
            catch (Exception ex) { }
            TimeSpan ts = DateTime.Now - begin;//更新一万条数据2秒左右

外层一定要套一个空的catch语句,否则如果出现数据库中不存在的数据就会触发并发性错误终止程序,加上空catch则不会影响执行,同时需要在构造datatable的时候做一个存在性检查,这里使用select语句

 foreach (DataRow item in X.Rows)
                        {
                            string Find = "IDNo='{0}'";
                            Find = string.Format(Find, item.ItemArray[2].ToString().Trim());
                            if (basement.Select(Find).Length > 0)
                            {
                                string AreaZone = System.IO.Path.GetFileNameWithoutExtension(Path);
                                string Locations = item.ItemArray[0].ToString().Trim();

                                DataRow dr = dt.NewRow();
                                dr["MLocation"] = Locations;
                                dr["AreaZone"] = DataX.GetArea(Locations);
                                dr["AreaName"] = DataX.GetHome(Locations);
                                dr["IDNo"] = item.ItemArray[2].ToString().Trim();

                                dt.Rows.Add(dr);
                            }
                            Count++;
                            settext(Pbar, Count, lblValue, X.Rows.Count);
                        }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以通过以下步骤将Oracle数据写入SQL Server: 1. 使用Oracle的OLEDB提供程序连接到Oracle数据库。 ```c# string connString = "Provider=OraOLEDB.Oracle;Data Source=OracleDB;User ID=Username;Password=Password"; OleDbConnection conn = new OleDbConnection(connString); ``` 2. 使用SQL Server的.NET提供程序连接到SQL Server数据库。 ```c# string connString = "Data Source=SqlServerDB;Initial Catalog=DatabaseName;Integrated Security=True"; SqlConnection conn = new SqlConnection(connString); ``` 3. 使用OracleDataAdapter将数据从Oracle中检索出来。 ```c# string query = "SELECT * FROM OracleTable"; OleDbDataAdapter adapter = new OleDbDataAdapter(query, conn); DataTable dataTable = new DataTable(); adapter.Fill(dataTable); ``` 4. 使用SqlBulkCopy数据写入SQL Server。 ```c# SqlBulkCopy bulkCopy = new SqlBulkCopy(conn); bulkCopy.DestinationTableName = "SqlTable"; bulkCopy.WriteToServer(dataTable); ``` 完整的代码如下: ```c# string oracleConnString = "Provider=OraOLEDB.Oracle;Data Source=OracleDB;User ID=Username;Password=Password"; string sqlServerConnString = "Data Source=SqlServerDB;Initial Catalog=DatabaseName;Integrated Security=True"; using (OleDbConnection oracleConn = new OleDbConnection(oracleConnString)) { oracleConn.Open(); using (SqlConnection sqlServerConn = new SqlConnection(sqlServerConnString)) { sqlServerConn.Open(); string query = "SELECT * FROM OracleTable"; using (OleDbDataAdapter adapter = new OleDbDataAdapter(query, oracleConn)) { DataTable dataTable = new DataTable(); adapter.Fill(dataTable); using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlServerConn)) { bulkCopy.DestinationTableName = "SqlTable"; bulkCopy.WriteToServer(dataTable); } } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值