• SqlDataAdapter.Update批量数据更新


    使用SqlDataAdapter.Update可以方便地对数据库进行快速、批量数据更新。我们最常用的多条数据更新方法是使用循环多次执行SQL语句或存储过程,这样虽然方便,但由于连接和数据传递要在服务器和客户端多次来往,大大增加了整个过程的时间,当数据越大时越明显!

    使用SqlDataAdapter.Update更新有三种方式,即SqlCommandBuiler自动生成更新,使用配置数据源方式更新,手动编写命令

    SqlCommandBuiler方式:

     public static void AddInfo()
            {
                string str1 = "Server=.;user=sa;pwd=sa;database=One_db";
                SqlConnection conn = new SqlConnection(str1);
                conn.Open();
                SqlCommand cmd = new SqlCommand("select * from Info", conn);
                DataTable dt = new DataTable();
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                da.Fill(dt);
    
                for (int i = 0; i < 4; i++)
                {
                    dt.Rows.Add(new object[] { i + 4, "aa0" + i, "soft", "12345678945" });
                    
                }
                
                SqlCommandBuilder scb = new SqlCommandBuilder(da);
                da.Update(dt.GetChanges());
                dt.AcceptChanges();
                outValueDT(dt);////显示datatable信息
                conn.Close();
            }
    

     软件运行之前 数据库的数据为:

    运行之后的数据为:

    2、执行删除和修改命令

    public static void DeleteInfo()
            {
                string str1 = "Server=.;user=sa;pwd=sa;database=One_db";
                SqlConnection conn = new SqlConnection(str1);
                conn.Open();
                SqlCommand cmd = new SqlCommand("select * from Info", conn);
                DataTable dt = new DataTable();
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                da.Fill(dt);
    
                dt.Rows[0][1] = "wangyu";
                dt.Rows[1][3] = "13924658789";
           dt.Rows.RemoveAt(2); //dt.Rows[3].Delete(); SqlCommandBuilder scb = new SqlCommandBuilder(da); da.Update(dt.GetChanges()); dt.AcceptChanges(); outValueDT(dt); //显示datatable信息 conn.Close(); }

     如果没有设置主键  将会出现错误

    执行后将出错,错误信息“对于不返回任何键列信息的 SelectCommand,不支持 UpdateCommand 的动态 SQL 生成。”

    出错原因是建表时没有设置主键。主键唯一标识一行数据,SqlCommandBuilder是根据DataTable每行的RowState及对应的主键来生成命令的,没有主键就无法确定删除哪条数据,当然不可能根据其他列来删除,因为其他列可能重复,这样会删除多行数据,很可能执行后不是你想要的结果,这种不确定性的对数据的操作方法,微软当然不可能提供给你!

    使用dt.Rows.RemoveAt(2)  显示dt时,  发现 dt里面的索引值为2的行被删除,但是 数据库里面的相应行并没有被删除

    想要删除数据库里面的 需要使用dt.Rows[2].Delete(); 

    修改代码后   第0行第一列的数据  第1行第3列的数据 已经修改   ,索引值为2的row删除 数据库数据为:

    注意:

    使用RemoveAt或Remove会将数据真正的从DataTable中删除,而使用Delete则不会,而仅是把当前行的RowState值置为deleted.

    前面说过SqlCommandBuilder是根据RowState和主键来生成命令的,RemoveAt/Remove把数据删除了,怎么能找到主键和RowState呢?

    所以使用SqlCommandBuilder时应该注意的2点:表要有主键,应使用delete方法删除行.SqlCommandBuilder用来自动生成添加、删除、修改的语句

    在使用Update()这个函数前,我们得知道一点,那就是一个DataTable有个记录RowState的字段(不知称其为字段合适不合适),当我们对表进行过添加、修改、删除之后,这个RowState会记录我们的操作,而Update()方法正是根据RowState进行对数据库表的更新的。有点需要注意,那就是添加和删除操作:当我们使用Add()方法添加一个新行和Delete()方法删除一行的时候是没有问题的,DataTable都正确记录下来了我们的操作,并能在Update()函数下正确更新到数据库中,但是当我们使用Import()方法导入一行或Remove()删除一行的时候,我们此时再使用Update()方法,发现我们的添加和删除没有成功,这是为什么呢?我们分别来看一下:

    Import()方法,我们导入的是一个已经存在于其他表里的行,而这个被导入的行的RowState记录的是什么是不确定的,所以导入到我们的DataTable中的时候,我们的DataTable并不一定把这一行当作是添加的行;

    RemoveAt()方法,在我们使用RemoveAt()方法的时候,我们的DataTable并没有真正的把这一行删除了,而只是记录了一个删除状态,当我们使用DataTable的AcceptChanges()的时候,记录为删除状态的行才被真正删除了,而RemoveAt()方法是直接把行删除了,所以再使用Update()方法时没有实现对数据库对应表的行删除功能

        当我们完成了Update()函数之后应该调用DataTable()的AcceptChanges()方法,把DataTable的RowState记录初始化。用进行过RowState初始化(即调用过AcceptChanges ())的DataTable去Update()数据库中的表,将不会进行任何更新。

    我在项目里用这个Update()方法的时候是这么用的:我并不是从数据库中先读出一张DataTable,进行一些添加或删除或修改,然后Update(),而是我有一张现成的dataTable,我最初的想法是想让我的这张DataTable和数据库中对应的表进行对比,然后根据两张表的不同之处进行更新,但实际上这是无法实现的,是我最初没有真正明白Update()函数的原理。所以,SqlDataAdapter的Update()方法不是拿数据库中的表和程序中的一个DataTable进行对比更新,而是根据程序中的DataTable中记录的RowState进行更新。

    所以,我们想要使用这个Update()方法实现批量更新,必须让我们的DataTable正确记录所有的RowState,当更新完成后还应调用AcceptChanges()方法对DataTable的RowState进行初始化。

  • 相关阅读:
    mysql 游标查询
    mysql忘记root密码的解决
    java 两种缓存
    java 实现缓存
    android ndk
    本地计算机上的 MSSQLSERVER 服务启动后又停止了。一些服务自动停止,如果它们没有什么可做的,例如“性能日志和警报”服务 [解决办法]
    选择WEB开发语言
    linux 查看硬件信息
    java 缓存 谈
    程序员相关
  • 原文地址:https://www.cnblogs.com/rosesmall/p/8568636.html
Copyright © 2020-2023  润新知