SqlCommandBuilder 可批量新增与修改数据

一、简述

  在项目中有一个需要导入数据包的需求,数据包是一个XML的文件,里面存储有数据,那么读取文件后就形成一个DataTable,然后改怎么把这个DataTable的数据批量插入到数据库里面去呢?用一个循环?循环虽然简单,但总结的有点别扭,所以还是用SqlCommandBuilder、SqlDataAdapter.update来批量插入数据吧。

二、内容

首先数据库的原数据

然后批量插入数据的代码

    private string con = "Data Source=.;Initial Catalog=TestDatabase;Integrated Security=True";
    private void DataBatchUpdate()
    {
        // 假数据
        DataTable dt = new DataTable();
        dt.Columns.Add("id", typeof(int));
        dt.Columns.Add("testName");

        DataRow dr = dt.NewRow();
        dr["id"] = "1";
        dr["testName"] = "白白";
        dt.Rows.Add(dr);

        SqlConnection sqlCon = new SqlConnection(con);
        SqlDataAdapter sqlDa = new SqlDataAdapter("select * from testDataTable ", sqlCon);
        DataSet sqlds = new DataSet();
        sqlDa.Fill(sqlds);

        // 数据库数据
        DataTable databaseData = sqlds.Tables[0];
        databaseData.Merge(dt);

        SqlCommandBuilder sqlcb = new SqlCommandBuilder(sqlDa);
        sqlDa.Update(databaseData);
    }

得出来的数据,里面就新增了一条数据

  这里主要是 Merge 起来合并两张Table表,然后由SqlCommandBuilder与Update()来更新到数据。然而,函数Update() 是根据DataTable的RowState来更新表的。当用Merge合并了两张表后,各行的RowState就像下图

这里,先在原来代码的基础添加几行代码

    private string con = "Data Source=.;Initial Catalog=TestDatabase;Integrated Security=True";
    private void DataBatchUpdate()
    {
        // 假数据
        DataTable dt = new DataTable();
        dt.Columns.Add("id", typeof(int));
        dt.Columns.Add("testName");

        DataRow dr = dt.NewRow();
        dr["id"] = "1";
        dr["testName"] = "白白";
        dt.Rows.Add(dr);

        SqlConnection sqlCon = new SqlConnection(con);
        SqlDataAdapter sqlDa = new SqlDataAdapter("select * from testDataTable ", sqlCon);
        DataSet sqlds = new DataSet();
        sqlDa.Fill(sqlds);

        // 数据库数据
        DataTable databaseData = sqlds.Tables[0];
        databaseData.Merge(dt);

        // 显示表格没一行的状态
        databaseData.Columns.Add("updatedSate");
        for (int i = 0; i < databaseData.Rows.Count; i++)
        {
            DataRow updatedRow = databaseData.Rows[i];
            updatedRow["updatedSate"] = updatedRow.RowState;
        }

        //SqlCommandBuilder sqlcb = new SqlCommandBuilder(sqlDa);
        //sqlDa.Update(databaseData);

        gridData.DataSource = databaseData;
        gridData.DataBind();

    }

得出的结果则显示最后一条的状态是 Added,所以就作为新数据插入到数据库去。

那么,如果只是批量插入数据的话

SqlDataAdapter sqlDa = new SqlDataAdapter("select * from testDataTable ", sqlCon);

还可以这么写,就是获取到数据库表中的结构就可以了。

SqlDataAdapter sqlDa = new SqlDataAdapter("select * from testDataTable where 1=2", sqlCon);

  那么,如果只是单纯的批量插入数据库就简单多了,可是项目的导入数据包功能,如果用户是重复导入了呢?又或者导入的数据当中只有几个单元格的数据跟数据库的数据不同的呢?这该怎么解决?嗯??在代码中写个几句代码判断导入的数据在数据库表中是否存在,存在就把数据库表中的数据删掉,再新插入进去? - - !  显然不靠谱。

  后来就发现了有一种很神奇的方法,因为代码中的Update()是根据RowState来判断是否增删改的,上面只用到了“增”,那么只要RowsState是“改”就可以了。

首先代码

    private string con = "Data Source=.;Initial Catalog=TestDatabase;Integrated Security=True";
    private void DataBatchUpdate()
    {
        // 假数据
        DataTable dt = new DataTable();
        dt.Columns.Add("id", typeof(int));
        dt.Columns.Add("testName");

        DataRow dr = dt.NewRow();
        dr["id"] = "1";
        dr["testName"] = "白白";
        dt.Rows.Add(dr);

        SqlConnection sqlCon = new SqlConnection(con);
        SqlDataAdapter sqlDa = new SqlDataAdapter("select * from testDataTable ", sqlCon);
        DataSet sqlds = new DataSet();
        sqlDa.Fill(sqlds);

        // 数据库数据
        DataTable databaseData = sqlds.Tables[0];

        databaseData.PrimaryKey = new DataColumn[] { databaseData.Columns["id"] };  //设置DataTable的主键

        databaseData.Merge(dt);

        // 显示表格没一行的状态
        databaseData.Columns.Add("updatedSate");
        for (int i = 0; i < databaseData.Rows.Count; i++)
        {
            DataRow updatedRow = databaseData.Rows[i];
            updatedRow["updatedSate"] = updatedRow.RowState;
        }

        SqlCommandBuilder sqlcb = new SqlCommandBuilder(sqlDa);
        sqlDa.Update(databaseData);

        gridData.DataSource = databaseData;
        gridData.DataBind();

    }

关键是为DataTable设置主键,然后Merge()就会自动修改,其RowState就变成了“改”,并且Name也随之变了。

  《=修改后    《=修改前

这样就可以实现在相同的ID下自动批量更新数据的效果。  注:Update()更新数据的时候,数据库表中结构要有主键才可以。

时间: 2024-11-07 01:35:16

SqlCommandBuilder 可批量新增与修改数据的相关文章

批量新增百万条数据 十百万条数据

--创建用户表CREATE TABLE table_1(    id int PRIMARY KEY, -- 主键ID    c1 varchar(24) NOT NULL,-- 列1    c2 datetime NOT NULL -- 列2) -- 批量新增一万条数据CREATE PROCEDURE PROC_INSERT @max int = 1000000, @c1 int = 1as WHILE @c1  <= @maxBEGIN  INSERT INTO Table_1 VALUES

mybatis,批量新增、修改,删除

转载自:http://blog.csdn.net/sanyuesan0000/article/details/19998727 最近需要用到Mybatis批量新增oracle数据库,刚开始在网上找到的方法是都是更新mySQL的,试了一下发现不适合Oracle,后来发现正确的oracle批量新增的sql是: <insert id="insertAttractionsBatch" parameterType="java.util.List"> insert

c#调用存储过程实现批量增加和修改数据

1 例如当我在编辑表格数据,一次编辑了多行需要保存到数据库时,就需要判断数据库中是否已经存在,存在则修改,不存在则新增一条或多条数据,即所谓批量增加或者跟新数据. 首先需要构建数据包,把要添加或者跟新的数据构建成一个datatable,例如我数据库中的表结构是这样 CREATE TABLE [dbo].[FlagDescription]( [FundId] [CHAR(10)] not null, [SurveyType] [tinyint] not null, [DefectReason] T

mybatis 学习笔记(4) —— 批量新增数据

1.业务是从前台传入List<T> ,在controller层接受参数,并进行批量新增操作. 2.需要处理的细节 a) mybatis可以支持批量新增,注意数据表需要将主键设置成自增列. b) 由于spring mvc 无法将参数[{id:0,text:'a'},{id:1,text:'b'}] json字符串转换为对应的List<T>,因此需要自己手动封装一个方法用于将传入的字符串转换为泛型集合 3.具体实现步骤 a) js提交 需要注意的是必须在参数名上加引号 var dept

批量导入是批量修改还是批量新增

1.一般基础数据信息的管理功能包括   新增.修改.删除.查询.导入.导出,比如物料信息维护: 这里说到的导入即相对于新增来说,即批量新增的功能: 2.当我所有的数据信息都完善了的情况下,由于业务的变更,需要给这些基础数据信息新增一个字段信息A:这个时候怎么办? 3.注:在新增.修改.导入模块都增加了字段信息A; 方案1.我做一个批量修改导入的模块,取物料信息的唯一字段标识与要导入的字段A,2列,单独去导入,实现批量修改的功能,用户自己去导入: 方案2.用户提供要导入的信息,包括物料信息的唯一标

ASP.NET MVC用存储过程批量添加修改数据

用Entity Framework 进行数据库交互,在代码里直接用lamda表达式和linq对数据库操作,中间为程序员省去了数据库访问的代码时间,程序员直接可以专注业务逻辑层的编写.但是对于比较复杂的表关系关联查询或者修改就比较费劲了.通常可以采用的方式是用EF执行SQL语句或者"存储过程",特别是执行复杂批量任务,当然也可以在MVC底层用ADO.NET,这里就不多说了.怎么做批量呢?这里讲讲在EF下用存储过程批量添加修改数据. 需求是这样的:需要批量添加修改产品类别的投放任务数额,每

关于项目中批量修改数据

一.在项目中批量修改数据时应该写一条Update的Sql语句来执行,不能先将所要修改的数据筛选出来,然后再遍历修改. 原因: 1.这样只操作一次数据库,而后者需要操作无数次,性能很差. 2.绕圈子.需要修改数据时直接修改就行,不需要先全部查出来再逐条修改. 3.修改数据时时可以使用join的,例如: 1 update acc set acc.Creator = '滕晓梅' 2 from Accidents acc 3 inner join CompensationCase cc on acc.I

批量修改数据sql

--insert into P_ZPROMOTION_DOC_ITEMS (AKTNR,MATNR,MINGROSS,MCRANK,MCUPRICE,MAXBAKTNR,MAXBPAMONT,MAXBPRICE,MINBAKTNR,MINBPAMONT,MINBPRICE) SELECT AKTNR4,MATNR,MINGROSS,MCRANK,MCUPRICE,MAXBAKTNR,MAXBPAMONT,MAXBPRICE,MINBAKTNR,MINBPAMONT,MINBPRICE FROM

批量新增,每500条数据新增一次

直接上代码 // 商品信息,每500条批量新增一次 if(null != itemList && itemList.size() > 0){ Map<Integer,List<Item>> itemMap = new HashMap<Integer, List<Item>>(); itemMap.put(1, new ArrayList<Item>()); for(Item item : itemList){ List<