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

一.数据的插入

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, , "devid");
sd.InsertCommand.Parameters.Add("@data_time", SqlDbType.Char, , "data_time");
sd.InsertCommand.Parameters.Add("@data_value", SqlDbType.Int, , "data_value");
sd.InsertCommand.UpdatedRowSource = UpdateRowSource.None;
sd.UpdateBatchSize = ; DataSet dataset = new DataSet();
sd.Fill(dataset);
Random r = new Random();
for (int i = ; i < ; i++) {
object[] row = {"DEVID"+i,DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),r.Next(,) };
dataset.Tables[].Rows.Add(row);
if (i % == ) {
sd.Update(dataset.Tables[]);
dataset.Tables[].Clear();
}
}
sd.Update(dataset.Tables[]);
dataset.Tables[].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(); 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, , "data_time");
sd.UpdateCommand.Parameters.Add("@data_value", SqlDbType.Int, , "data_value");
sd.UpdateCommand.Parameters.Add("@devid", SqlDbType.Char, , "devid");
sd.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
sd.UpdateBatchSize = ;
for (int count = ; count < ;)
{ for (int i = ; i < ; i++,count++)
{
dataset.Tables[].Rows[i].BeginEdit();
dataset.Tables[].Rows[i]["data_time"] = "2222-22-22 22:22:22";
dataset.Tables[].Rows[i]["data_value"] = ;
dataset.Tables[].Rows[i]["devid"] = "DEVID"+count;
dataset.Tables[].Rows[i].EndEdit();
}
sd.Update(dataset.Tables[]);
} dataset.Tables[].Clear();
sd.Dispose();
dataset.Dispose

C#使用SqlDataAdapter 实现数据的批量插入和更新的更多相关文章

  1. Hibernate 数据的批量插入、更新和删除

    4.2  Hibernate的批量处理 Hibernate完全以面向对象的方式来操作数据库,当程序里以面向对象的方式操作持久化对象时,将被自动转换为对数据库的操作.例如调用Session的delete ...

  2. MSSQL数据的批量插入

    一.概述: 对于数据的批量插入操作似乎成了某些大数据量操作的必用手段,MSSQL也提供了一些数据批量插入的操作方法,先将这些方法汇总,以便于下次用到使用.面对数据的批量插入操作,我们也应该考虑一个问题 ...

  3. postgresql优化数据的批量插入

    原文:http://www.cnblogs.com/mchina/archive/2012/08/11/2537393.html 有以下几种方法用于优化数据的批量插入. 1. 关闭自动提交:      ...

  4. MySQL 避免重复数据的批量插入与批量更新

    [转发] 导读 我们在向数据库里批量插入数据的时候,会遇到要将原有主键或者unique索引所在记录更新的情况,而如果没有主键或者unique索引冲突的时候,直接执行插入操作. 这种情况下,有三种方式执 ...

  5. mybatis 注解的方式批量插入,更新数据

    一,当向数据表中插入一条数据时,一般先检查该数据是否已经存在,如果存在更新,不存在则新增  使用关键字  ON DUPLICATE KEY UPDATE zk_device_id为主键 model  ...

  6. MySQL on duplicate key update 批量插入并更新已存在数据

    业务上经常存在一种现象,需要批量往表中插入多条数据,但在执行过程中,很可能因为唯一键冲突,而导致批量插入失败.因此需要事先判断哪些数据是重复的,哪些是新增的.比较常用的处理方法就是找出已存在的数据,并 ...

  7. Hibernate批处理操作优化 (批量插入、更新与删除)

    问题描述 我开发的网站加了个新功能:需要在线上处理表数据的批量合并和更新,昨天下午发布上线,执行该功能后,服务器的load突然增高,变化曲线异常,SA教育了我一番,让我尽快处理,将CPU负载降低. 工 ...

  8. MySQL(四) 数据表的插入、更新、删除数据

    序言 数据表的插入.更新.删除非常简单,但是简单的也要学习,细节决定成败. ---WH 一.插入数据 格式:INSERT INTO 表名(字段名...)VALUES(值...); 创建环境 使用per ...

  9. java批量插入或更新的问题

    在批量插入或者更新中,setXXX的时候字段类型必须一致.例如:在普通sql中 pstmt8.setBigDecimal(j ,xxx);可以写成pstmt8.setString(j,xxx.toSt ...

随机推荐

  1. STM8S TIM4 初始化设置

    #define TIM4_DIV1 (unsigned char)0 #define TIM4_DIV2 (unsigned char)1 #define TIM4_DIV4 (unsigned ch ...

  2. 通过qsort(void * lineptr[], int left, int rifht, int (*comp)(void *, void *))解读指针函数和void指针

    原函数是<The C programint  language >5.11文本行排序的程序,如下: void qsort(void *v[], int left, int right, i ...

  3. Java 在本地文件中查找固定字符串

    适用范围:只适用于在文本文档中查找(如,txt.java.c等等,并不适用与doc.xls等等这些文件),可嵌套文件夹.但是对中文不支持. 例如:文件夹:F:/demo 子文件夹:F:/demo/er ...

  4. vsftpd配置seccomp_sandbox=NO

    在ubuntu14.04 配置vsftp时如果不加上seccomp_sandbox=NO这一句会出现莫名的530错误

  5. Android KeyLogger Demo

    @author: dlive 代码见github: https://github.com/Dliv3/Android-KeyLogger-Demo 前言 之前开发过一个Android的木马,其中Key ...

  6. Eclipse 中,web项目在Tomcat运行时填写不了Server name

    最近开发项目,从MyEclipse中导入项目到Eclipse中,那些WEB属性都在,可就是不能在Tomcat上运行.纠结一番,最后发现是这个问题: WEB的版本问题. 具体问题看下图: 解决方案: W ...

  7. C语言之变量与常量的介绍

    一 标示符 标识符:可以理解为是变量名.名字常量表示法的常量名,但是不仅限于这两个 命名规范: 1.起名要有意义,基本要做到一看名字就知道是用来干嘛的(要求你遵守,但不会报错,希望能够养成这样的好习惯 ...

  8. 《Python高效开发实战》实战演练——内置Web服务器4

    <Python高效开发实战>实战演练——开发Django站点1 <Python高效开发实战>实战演练——建立应用2 <Python高效开发实战>实战演练——基本视图 ...

  9. linux面试题集锦3《转》

    三.简答题: 1.简述Linux文件系统通过i节点把文件的逻辑结构和物理结构转换的工作过程. 参考答案: Linux通过i节点表将文件的逻辑结构和物理结构进行转换. i节点是一个64字节长的表,表中包 ...

  10. Method Invocation Expressions

      15.12.1. Compile-Time Step 1: Determine Class or Interface to Search   The first step in processin ...