zoukankan      html  css  js  c++  java
  • [转]用SqlCommandBuilder 实现批量更新

    (一)

      有没有人遇到这种情况,用 SqlDataAdapter.Update(ds)更新时出错?

      answer:   一般是这样的,如果用设计器将SqlDataAdapter拖到页面中使用时,不会出现这种情况,因为

                      系统会自动生成SqlDataAdapter的属性命令,比如:  .UpdateCommane insertCommand

                      selectCommand等。  但是有些程序员不喜欢用设计器,或者是有些地方没必要拖动

                      SqlDataAdapter这么个庞大物来实现,那么SqlDataAdapter就不会自动生成相关的查询或更新

                      语句了.   所以当执行到SqlDataAdapter.Update(ds)语句时,SqlDataAdapter桥接器不知道更

                     新哪个表.就报错了. 

    (二)

      解决方法:

      用SqlCommandBuilder 实现批量更新

      1.功能:

       可以实现你对DataSet在UI层做任意操作后,直接丢给这个方法,这个方法就可以自动把你的修改更 新到数 据库中,而没必要每次都更新到

       数据库

      2.使用方法
      public DataSetUpdateByDataSet(DataSet ds,string strTblName,string strConnection)
      {
          SqlConnection  conn = new SqlConnection(strConnection));
            
         SqlDataAdapter myAdapter = new SqlDataAdapter();
         SqlCommand myCommand = new SqlCommand("select * from "+strTblName),(SqlConnection) conn);   
         myAdapter.SelectCommand = myCommand;
         SqlCommandBuilder myCommandBuilder = new SqlCommandBuilder(myAdapter);    
      try

          {  

                   lock(this)            //处理并发情况(分布式情况)

                  {

                   myAdapter.Update(ds,strTblName); 

                  }

          }  
     
      catch(Exception err)
     {

       conn.Close();   
       throw new BusinessException(err);
     }

        return ds;    //数据集的行状态在更新后会都变为: UnChange,在这次更新后客户端要用返回的ds

    }

    public DataSet UpdateByDataSet(DataSet ds,string strTblName,string strConnection)
      {
       
      
          SqlConnection  conn = new SqlConnection(strConnection));         
          SqlCommand myCommand = new SqlCommand("select * from "+strTblName),(SqlConnection) conn);   

          SqlDataAdapter myAdapter = new SqlDataAdapter(myCommand );   

          SqlCommandBuilder myCommandBuilder = new SqlCommandBuilder(myAdapter);     
          
          myAdapter.InsertCommand = myCommandBuilder .GetInsertCommand();

          myAdapter.UpdateCommand = myCommandBuilder .GetUpdateCommand();

         myAdapter.DeleteCommand = myCommandBuilder .GetDeleteCommand();

       try

      {

            lock(this)                              //处理并发情况(分布式情况)

           {

                  conn.Open();

                  myAdapter.Update(ds,strTblName);  

                  conn.Close();

           }
      
             return ds;    //数据集的行状态在更新后会都变为: UnChange,在这次更新后客户端要用返回的ds }
     catch(Exception err)
     { 

          conn.Close(); 
          throw new BusinessException(err);
     }
    }

    直接调用这两个方法的任意一个就OK啦,说明的一点是select * from "+strTblName是一定要的,
    作用大家也应该想到了,主要是告诉 SqlDataAdapter更新哪个表


    3.什么时候用?

        a. 有时候需要缓存的时候,比如说在一个商品选择界面,选择好商品,并且进行编辑/删除/更新后,

           最后一并交给数据库,而不是每一步操作都访问数据库,因为客户选择商品可能进行n次编辑/删除

           更新操作,如果每次都提交,不但容易引起数据库冲突,引发错误,而且当数据量很大时在用户执行

           效率上也变得有些慢

        b.有的界面是这样的有的界面是这样的,需求要求一定用缓存实现,确认之前的操作不提交到库,点击

          页面专门提交的按钮时才提交商品选择信息和商品的其它信息. 我经常遇到这样的情况

        c.有些情况下只往数据库里更新,不读取. 也就是说没有从数据库里读,SqlDataAdapter也就不知道是
        
          更新哪张表了,调用Update就很可能出错了。这样的情况下可以用SqlCommandBuilder 了.
            

    4.
     注意点:
      1.只能更新一个表,如果此数据集是从两个或者两个以上的表关联而来的,则不能用此方法自动更新
      2.表中必须设置主键
      3.更新的表中字段不能有image类型的

    5.优点:

        节省代码量,节省时间,这个方法可以代替所有的:  更新/删除/插入操作语句

    6.缺点:
            访问两次数据库(select * TableName,就是这句,要确认是哪个表,除非是很大的数据量,
            一般是感觉不到的),效率稍微有些慢

    谢谢阅读!

  • 相关阅读:
    14.18 InnoDB Backup and Recovery 备份和恢复:
    14.18 InnoDB Backup and Recovery 备份和恢复:
    php使用 _before_index() 来实现访问页面前,判断登录
    php使用 _before_index() 来实现访问页面前,判断登录
    查询方式实例演示
    查询方式实例演示
    haproxy timeout server 46000 后台超时时间
    haproxy timeout server 46000 后台超时时间
    14.10.5 Reclaiming Disk Space with TRUNCATE TABLE 回收空间使用TRUNCATE TABLE
    14.10.5 Reclaiming Disk Space with TRUNCATE TABLE 回收空间使用TRUNCATE TABLE
  • 原文地址:https://www.cnblogs.com/chengulv/p/666662.html
Copyright © 2011-2022 走看看