由于要录入大量的数据,使用sqlcommand.executenonquery()方法向数据库中插入数据,使得程序运行缓慢,无法满足程序使用要求,就在考虑什么方法能够进行数据的批量处理,最后发现了另外两种性能优异的方法,解决了速度的问题。那么现在就介绍一下两种方法,一种是SqlDataAdapter的Update(dataTable)方法,另一种是SqlBulkCopy类。
下面我们通过两种方法进行测试,以录入1万条数据来检测运行效率和注意事项
· 引用的命名空间
1 using System.Data; 2 using System.Data.SqlClient;
· 创建数据库
//create database TestDB //CREATE TABLE [dbo].[t_Data]( // [ID] [int] IDENTITY(1,1) NOT NULL, // [Name] [nvarchar](50) NULL, // [Address] [nvarchar](50) NULL //) ON [PRIMARY]
· SqlBulkCopy类
private void btnTest_Click(object sender, EventArgs e) { // 定义与目标表的结构一致的内存表 排除自增id列 DataTable dtSource = new DataTable(); //列名称如果和目标表设置为一样,则后面可以不用进行字段映射 dtSource.Columns.Add("NameS", typeof(string)); dtSource.Columns.Add("AddressS", typeof(string)); // 向dt中增加1W条测试数据 DataRow dr; for (int i = 0; i < 100 * 100; i++) { // 创建与dt结构相同的DataRow对象 dr = dtSource.NewRow(); dr["NameS"] = "Name" + i; dr["AddressS"] = "Address" + i; // 将dr追加到dt中 dtSource.Rows.Add(dr); } //将内存表dt中的1W条数据一次性插入到t_Data表中的相应列中 System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch(); st.Start(); string connStr = "server=.;database=TestDB;uid=sa;pwd=123456;"; using (System.Data.SqlClient.SqlBulkCopy copy = new System.Data.SqlClient.SqlBulkCopy(connStr)) { //1 指定数据插入目标表名称 copy.DestinationTableName = "t_Data"; //2 告诉SqlBulkCopy对象 内存表中的 OrderNO1和Userid1插入到OrderInfos表中的哪些列中 copy.ColumnMappings.Add("NameS", "Name"); copy.ColumnMappings.Add("AddressS", "Address"); //3 将内存表dt中的数据一次性批量插入到OrderInfos表中 copy.WriteToServer(dtSource); } st.Stop(); MessageBox.Show("数据插入成功,总耗时为:" + st.ElapsedMilliseconds + "毫秒"); }
经过运行,录入1万条数据所需时间为:
· SqldataAdapter.Update(dataset,tablename)
private void button1_Click(object sender, EventArgs e) { //1.0 定义与目标表的结构一致的内存表 排除自增id列 DataTable dtSource = new DataTable(); //列名称如果和目标表设置为一样,则后面可以不用进行字段映射 dtSource.Columns.Add("ID", typeof(string)); dtSource.Columns.Add("Name", typeof(string)); dtSource.Columns.Add("Address", typeof(string)); //2.0 向dt中增加1W条测试数据 DataRow dr; for (int i = 0; i < 100*100; i++) { //1.0 创建与dt结构相同的DataRow对象 dr = dtSource.NewRow(); dr["Name"] = "NameId" + i; dr["Address"] = "AddressId" + i; //2.0 将dr追加到dt中 dtSource.Rows.Add(dr); } System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch(); //计算时间 st.Start(); string conn = "server=.;database=TestDB;uid=sa;pwd=123456;"; //连接数据库 string sqlText = "select * from t_Data"; //SQL语句,用于查出符合条件的数据库数据 //当上述工作完成之后,我们调用SqlDataAdapter的Fill()方法,将查询出来的数据表内容填充的一张DataTable里面 SqlDataAdapter SDA = new SqlDataAdapter(sqlText, conn); SDA.Fill(dtSource); //这个SqlCommandBuilder用来自动生成添加、删除、修改的语句,注意这个参数是刚才建立的SqlDataAdapter。 SqlCommandBuilder SCB = new SqlCommandBuilder(SDA); SDA.Update(dtSource); //数据录入 st.Stop(); MessageBox.Show("数据插入成功,总耗时为:" + st.ElapsedMilliseconds + "毫秒"); } }
注意:这个方法要求DataTable表数据结构和字段对应是相同的。
经过运行
,录入1万条数据所需时间为:
所以:经过对比发现,SqlBulkCopy类的执行效率明显比SqlDataAdapter的Update(dataTable)方法快。