C#使用SqlDataAdapter 实现数据的批量插入和更新

摘要:
1、 数据插入DateTimebegin=DateTime。现在@data_value);sd.UpdateBatchSize=0;for(inti=0;dataset.Tables[0]。Rows.Add(row);})sd.Update(dataset.Tables[0]);}TimeSpants=DateTime.Now-begin;“数据时间”);

近日由于项目要求在需要实现中型数据的批量插入和更新,晚上无聊,在网上看到看到这样的一个实现方法,特摘抄过来,以便以后可能用到参考。

一.数据的插入

DateTime begin = DateTime.Now;
string connectionString = ......;
using(SqlConnection conn = new SqlConnection(connectionString)){
    conn.Open();
    SqlDataAdapter sd = new SqlDataAdapter();
    sd.SelectCommand = new SqlCommand("select devid,data_time,data_value from CurrentTest", conn);
    sd.InsertCommand = new SqlCommand("insert into CurrentTest (devid,data_time,data_value) "
                    + " values (@devid,@data_time,@data_value);", conn);
    sd.InsertCommand.Parameters.Add("@devid", SqlDbType.Char, 18, "devid");
    sd.InsertCommand.Parameters.Add("@data_time", SqlDbType.Char, 19, "data_time");
    sd.InsertCommand.Parameters.Add("@data_value", SqlDbType.Int, 8, "data_value");
    sd.InsertCommand.UpdatedRowSource = UpdateRowSource.None;
    sd.UpdateBatchSize = 0;

    DataSet dataset = new DataSet();
    sd.Fill(dataset);
    Random r = new Random(1000);
    for (int i = 0; i < 100000; i++) {
        object[] row = {"DEVID"+i,DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),r.Next(1,1000) };
        dataset.Tables[0].Rows.Add(row);
        if (i % 300 == 0) {
            sd.Update(dataset.Tables[0]);
            dataset.Tables[0].Clear();
        }
    }
    sd.Update(dataset.Tables[0]);
    dataset.Tables[0].Clear();
    sd.Dispose();
    dataset.Dispose();
    conn.Close();
   
}
TimeSpan ts = DateTime.Now - begin;
MessageBox.Show("ts = " + ts.TotalMilliseconds);

二.数据的更新

  作者原话引出:     

              对于这个测试我插入10万条数据用时28秒.性能还算可圈可点.但是对于批量更新,搜遍全球的例子,都是把记录Fill到DataSet中然后牧举rows
来更新,就我这个小数据量的测试而言,把10万条数据Fill到DataSet中已经不能工作,如果是百万,千万如何操作?难道一定先把要批操作的记录
先获取到DataSet中?也就是我要更新哪些记录就要选查询这些记录?

 于是我仍然利用一个空的DataTable来加入要更新的记录:

 sd.SelectCommand = new SqlCommand("select devid,data_time,data_value from CurrentTest where 1=0", conn);
 //1=0的条件保证取一个空表.
 sd.UpdateCommand = new SqlCommand("update CurrentTest set data_time = @data_time,data_value = @data_value where devid = @devid", conn);
        sd.UpdateCommand.Parameters.Add("@data_time", SqlDbType.Char, 19, "data_time");
        sd.UpdateCommand.Parameters.Add("@data_value", SqlDbType.Int, 4, "data_value");
        sd.UpdateCommand.Parameters.Add("@devid", SqlDbType.Char, 20, "devid");
        sd.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
        sd.UpdateBatchSize = 0;

 for(int i=0;i<300;i++){
  ..............................
  dataset.Tables[0].Rows.Add(row);
 }
 sd.Update(dataset.Tables[0]);
 先更新300条试试,如果成功再循环更新所有记录,但提示插入操作需要InsertCommand,因为一个空表然后Add Row操作,这时RowState是Added,

如果这时Update到数据库,执行的就是插入操作而无法更新. 改成:
 for(int i=0;i<300;i++){
  ..............................

 row = {填入初始化的值};
  dataset.Tables[0].Rows.Add(row);
 }
 dataset.AcceptChanges();
 for(int i=0;i<300;i++){
  ..............................
  dataset.Tables[0].Rows[i][x] = "xxxxxxx";
  ..............................
 }
 sd.Update(dataset.Tables[0]);
 先在DataTable中插入数据,然后用AcceptChanges(),修改RowState为UnChanged,再修改表中数据希望改变UnChanged状态,即将

DataTable从Current状态改为Original,然后再对DataTable的Row进行更新,就能使

Update成功.但这样做确实不方便.


 调整思路,先从数据库中取200条(批更新的Size大小),直接得到一个Original的DataTable.

 sd.SelectCommand = new SqlCommand("select top 200 devid,data_time,data_value from CurrentTest", conn);
 DataSet dataset = new DataSet();
        sd.Fill(dataset);
 用这200个空间来放要更新的其它数据看看:
 
                    for (int i = 0; i < 100; i++)
                    {
                        dataset.Tables[0].Rows[i].BeginEdit();
                        dataset.Tables[0].Rows[i]["data_time"] = "2222-22-22 22:22:22";
                        dataset.Tables[0].Rows[i]["data_value"] = 100;
                        dataset.Tables[0].Rows[i]["devid"] = "DEVID"+(i+10000);//更新DEVID10000到DEVID10200的记录
                        dataset.Tables[0].Rows[i].EndEdit();
                    }
                    sd.Update(dataset.Tables[0]);
 OK,成功,哈哈.把要更新的数据不断往这个空间填,填满就提交,这样更新100000条数据只要几个循环就行了.

DateTime begin = DateTime.Now;
            string connectionString = "";
            using(SqlConnection conn = new SqlConnection(connectionString)){
                conn.Open();

                SqlDataAdapter sd = new SqlDataAdapter();
                sd.SelectCommand = new SqlCommand("select top 200 devid,data_time,data_value from CurrentTest", conn);

                DataSet dataset = new DataSet();
                sd.Fill(dataset);
                Random r = new Random(1000);

                sd.UpdateCommand = new SqlCommand("update CurrentTest "
                                + " set data_time = @data_time,data_value = @data_value where devid = @devid", conn);
                sd.UpdateCommand.Parameters.Add("@data_time", SqlDbType.Char, 19, "data_time");
                sd.UpdateCommand.Parameters.Add("@data_value", SqlDbType.Int, 4, "data_value");
                sd.UpdateCommand.Parameters.Add("@devid", SqlDbType.Char, 20, "devid");
                sd.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
                sd.UpdateBatchSize = 0;
                for (int count = 0; count < 100000;)
                {

                    for (int i = 0; i < 200; i++,count++)
                    {
                        dataset.Tables[0].Rows[i].BeginEdit();
                        dataset.Tables[0].Rows[i]["data_time"] = "2222-22-22 22:22:22";
                        dataset.Tables[0].Rows[i]["data_value"] = 100;
                        dataset.Tables[0].Rows[i]["devid"] = "DEVID"+count;
                        dataset.Tables[0].Rows[i].EndEdit();
                    }
                    sd.Update(dataset.Tables[0]);
                }
  

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

免责声明:文章转载自《C#使用SqlDataAdapter 实现数据的批量插入和更新》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇javascript 获取当前页面的URLc# datagridview 相关操作。下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python--集合-set

1 1 # 集合-set 2 2 # 集合是高中的要给概念 3 3 # 一堆确定的无序的唯一的数据, 集合中的每一个数据成为一个元素 4 4 5 5 # 集合的定义 6 6 s = set() 7 7 print(type(s)) 8 8 print(s) 9 9 10 10 # 此时大括号中一定要有...

Opentelemetry Collector的配置和使用

Collector的配置和使用 目录 Collector的配置和使用 Collector配置 Receivers Processors Exporters Service Extensions 使用环境变量 Collector的使用 部署到Kubernetes 部署Prometheus operator 使用Makefile 配置OpenT...

ADODB——RecordSet对象

转自网友,看着挺全就转了,供大家学习研究。 Recordset 对象的属性1、CursorType 属性 AdOpenForwardOnly: 仅向前游标,默认值。除了只能在记录中向前滚动外,与静态游标相同。当只需要在记录集中单向移动时,使用它可提高性能。(顾名思义,这种游标只能向前移动。然而,由于这种游标功能有限,将它用于系统资源时是非常有效的。) Ad...

深度学习之Batch归一化

前言            以下内容是个人学习之后的感悟,转载请注明出处~ Batch归一化   在神经网络中,我们常常会遇到梯度消失的情况,比如下图中的sigmod激活函数,当离零点很远时,梯度基本为0。为了 解决这个问题,我们可以采用Batch归一化。                                                 ...

第一个极小的机器学习的应用

  现在给出一个Web统计信息,他们存储着每小时的访问次数。每一行包含连续的小时和信息,以及该小时Web的访问次数。现在要解决的问题是,估计在何时访问量达到基础设施的极限。极限数据是每小时100000次访问。 1.读取数据: # 获取数据 filepath = r'C:UsersTDDesktopdataMachine Learning1400OS_01_...

IndexedDB:不仅仅是客户端持久化缓存技术ThingJS

本地缓存技术提升用户访问体验 IndexedDB(客户端缓存持久化)技术优势 大型3D项目本地缓存技术实测 简介:为提升用户访问体验,缩短项目加载时间,ThingJS平台推出3D场景本地缓存技术:IndexedDB,也称客户端缓存持久化技术。通俗来说,IndexedDB就是浏览器提供的本地数据库,它可以被网页脚本创建和操作,使用JSON数据格式。下面详...