using System.Data.SqlClient;
...
SqlConnection conn = new SqlConnection("...");
SqlDataAdapter da = new SqlDataAdapter("select ...", conn);
SqlCommandBuilder cb = new SqlCommandBuilder(da);  //关键一句
DataSet ds = new DataSet();
da.Fill(ds, "tablename");
ds.Tables[0].Rows[0][0] = "abc";
...
da.Update(ds, "tablename");try it.

解决方案 »

  1.   

    icyer所说的是自动更新的方法,通常可以用于批量更新。你如果只是更新单条记录,你必须给出SqlDataAdapter的UpdateCommand.
      

  2.   

    public DataSet CreateCmdsAndUpdate(DataSet myDataSet,string myConnection,string mySelectQuery,string myTableName) 
    {
        OleDbConnection myConn = new OleDbConnection(myConnection);
        OleDbDataAdapter myDataAdapter = new OleDbDataAdapter();
        myDataAdapter.SelectCommand = new OleDbCommand(mySelectQuery, myConn);
        OleDbCommandBuilder custCB = new OleDbCommandBuilder(myDataAdapter);    myConn.Open();    DataSet custDS = new DataSet();
        myDataAdapter.Fill(custDS);    //code to modify data in dataset here    //Without the OleDbCommandBuilder this line would fail
        myDataAdapter.Update(custDS);    myConn.Close();    return custDS;
     }
      

  3.   

    各位,大家说的我都知道,在beta2下也是这样做的,这些都没有问题,但是在中文正式版下我的数据库总也无法更新,现将一个最简单的例子放在这里,请大家帮我看一看有什么错误,再次强调,这些代码在beta2下是没有问题的,而在正式版下,编译没问题,但一旦更新数据就出错:“Insert方法错误”。
    代码:
     //数据定义:
    private DataRow myDataRow;
    private DataTable myDataTable;
    private OleDbConnection myAccessConn;
    private OleDbCommand myAccessCommand1;
    private OleDbDataAdapter myDataAdapter1;
    private DataSet myDataSet;
    private OleDbCommandBuilder custCB1;
    private System.Windows.Forms.DataGrid Grid;

    //初始化数据表
    private void Form1_Load(object sender, System.EventArgs e)
    {
    string strAccessConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=newdb.mdb";
    string strAccessSelect1 = "SELECT * FROM table1";
    myDataSet = new DataSet();
    myDataSet.Tables.Add("table1");
    myAccessConn = new OleDbConnection(strAccessConn);
    myAccessCommand1 = new OleDbCommand();
    myAccessCommand1.Connection = myAccessConn;
    myDataAdapter1 = new OleDbDataAdapter(myAccessCommand1);
    custCB1 = new OleDbCommandBuilder(myDataAdapter1);
    myDataTable = myDataSet.Tables["table1"];
    myAccessConn.Open();
    try
    {
    myDataAdapter1.SelectCommand.CommandText=strAccessSelect1;
    myDataAdapter1.Fill(myDataSet,"table1");
    }
    catch(Exception err)
    {
    MessageBox.Show(err.Message.ToString());
    }

    Grid.SetDataBinding(myDataSet,"table1");
    }//添加纪录
    private void button1_Click(object sender, System.EventArgs e)
    {
    myDataRow = myDataTable.NewRow();
    myDataRow[0] = myDataTable.Rows.Count + 2;
    myDataRow[1] = textBox2.Text;
    myDataRow[2] = textBox3.Text;
    myDataTable.Rows.Add(myDataRow);
    button3_Click(sender,e);

    }
    //更新数据表
    private void button3_Click(object sender, System.EventArgs e)
    {
    DataSet Xdataset;
    Xdataset = myDataSet.GetChanges();
    try
    {
    if(Xdataset!=null)
    {
               myDataAdapter1.Update(Xdataset,"table1");
    }
    }
    catch(Exception err)
    {
    MessageBox.Show(err.Message.ToString());
    }
    }
      

  4.   

    求求大家了,请大家在正式版上用oledb连接一个最简单的access数据库,看看我的程序有没有问题,拜托了!
      

  5.   

    private void button3_Click(object sender, System.EventArgs e)
    {
    DataSet Xdataset;
    Xdataset = myDataSet.GetChanges();
    try
    {
    if(Xdataset!=null)
    {
               myDataAdapter1.Update(Xdataset,"table1");加上这句看看     myDataSet.AcceptChanges();
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
    }
    }
    catch(Exception err)
    {
    MessageBox.Show(err.Message.ToString());
    }
    }
      

  6.   

    我写的一个小程序与你的类似,也出现错误,症状是只能更新一次,如果第二次更新会出现concurrency violation :the update command affected 0 recorders我怀疑是不是SqlCommandBuilder方法本身有bug?
      

  7.   

    concurrency violation :the update command affected 0 recorders是因为update以后并不改变内部的标志位,getchanges函数调用返回的是
    上次改变以后的数据集合,这里上次改变是指从load以后或者acceptchange以后的改变,update并不等于acceptchange,所以要在update以后在调用acceptchange方法就可以了.
      

  8.   

    这些办法我都试了,都不行!各位都是用的正式版吗?
    我说过了,在beta版中是不存在问题的。
    我的系统配置是这样的:
    .net 7.0企业架构版(7cd)
    开发环境 version 7.0.9486
    .net Framework Version 1.0.3705
    Windows XP/P4 1.6G/512MB
      

  9.   

    各位,我也遇到这个问题。如果对DataSet所做的修改不能反映到数据库那还要它干什么?DataAdapter的Update()方法好像是没用的一样。有没有微软专家愿意回答这个问题?
    我查过网上的资料,大多数都是绕过DataAdapter而直接用DataCommand的ExecuteNonQuery()方法来解决的。
      

  10.   

    感谢您使用微软产品。我的系统和您的系统配置基本上一致:
    .net 7.0企业架构版(7cd)
    开发环境 version 7.0.9466(English Version)
    .net Framework Version 1.0.3705
    Windows XP/P4 1.6G/512MB经过我测试您提供的代码,发现了一些问题,供您参考:
    1,您出现的问题可能是这样的:数据表table1的第一个字段为主键(Primary Key)或设置为禁止字段值重复,如果您将数据表table1所有字段设置为普通的字段属性,本代码在运行时应该是没有问题的;
    2,但是您的代码实际上违背您的设计初衷:
    出现的问题是,如果您通过点击button1按钮来增加记录,假设点击按钮button1三次,则总共会增加(3+2+1 = 6)6条记录,因为每次Xdataset = myDataSet.GetChanges();时,会将前几次增加(修改)DataSet的信息再次获取,并Update到数据表table1中;
    DataSet Xdataset;
    Xdataset = myDataSet.GetChanges();
    try
    {
    if(Xdataset!=null)
    {
               myDataAdapter1.Update(Xdataset,"table1");
    }
    }
    catch(Exception err)
    {
    MessageBox.Show(err.Message.ToString());
    }
    3,因此,您应该在增加(修改)DataSet完成后,最后进行Update的操作。关于该DateSet的完整示例程序,请参考微软官方网站:
    http://chs.gotdotnet.com/quickstart/winforms/
     — 微软全球技术中心 VB支持中心本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利。具体事项可参见使用条款(http://support.microsoft.com/directory/worldwide/zh-cn/community/terms_chs.asp)。
    为了为您创建更好的讨论环境,请参加我们的用户满意度调查(http://support.microsoft.com/directory/worldwide/zh-cn/community/survey.asp?key=(S,49854782))。
      

  11.   

    我的数据表是用Access 2002制作的。数据库内只包含一个数据表,表里两个字段,都是字符型,没有索引。
    运行我的程序仍然提示“Insert方法错误”。
    请问微软专家,updata方法究竟能不能完成数据更新。
      

  12.   

    这句:custCB1 = new OleDbCommandBuilder(myDataAdapter1);
    最好在联接打开的状态下建立,即:
    //更新数据表
    private void button3_Click(object sender, System.EventArgs e)
    {
    DataSet Xdataset;
    Xdataset = myDataSet.GetChanges();
             myAccessConn.Open();
             custCB1 = new OleDbCommandBuilder(myDataAdapter1);
    try
    {
              if(Xdataset!=null)
    {
              myDataAdapter1.Update(Xdataset,"table1");
    }
    }
    catch(Exception err)
    {
    MessageBox.Show(err.Message.ToString());
    }
             fanally
             {
                   myAccessConn.Close();  
             }
    }
      

  13.   

    回复人: yuezh(张) (  ) 信誉:100  2002-04-10 11:38:00  得分:0  Top 
     
     我的数据表是用Access 2002制作的。数据库内只包含一个数据表,表里两个字段,都是字符型,没有索引。
    原来你没设主键啊  添一个吧 哪怕是无用的
     
     ================================================================CSDN 论坛助手 Ver 1.0 B0402提供下载。 改进了很多,功能完备!★  浏览帖子速度极快![建议系统使用ie5.5以上]。 ★  多种帖子实现界面。 
    ★  保存帖子到本地[html格式]★  监视您关注帖子的回复更新。
    ★  可以直接发贴、回复帖子★  采用XML接口,可以一次性显示4页帖子,同时支持自定义每次显示帖子数量。可以浏览历史记录! 
    ★  支持在线检测程序升级情况,可及时获得程序更新的信息。★★ 签名  ●  
         可以在您的每个帖子的后面自动加上一个自己设计的签名哟。Http://www.ChinaOK.net/csdn/csdn.zip
    Http://www.ChinaOK.net/csdn/csdn.rar
    Http://www.ChinaOK.net/csdn/csdn.exe    [自解压]
      

  14.   

    klxyz(小康)、 ty4278(test) :
    我以前的表都是有主键的,可是数据无法更新,acptvb(微软全球技术中心 VB技术支持) 在上面的帖子里说不加主键就可以,我才把主键删除了。另外请问二位,你们使用的是正式版吗?
      

  15.   

    感谢您使用微软产品。根据您的描述:
    ――――――――――――――――――――――――――――
    我的数据表是用Access 2002制作的。数据库内只包含一个数据表,表里两个字段,都是字符型,没有索引。
    ――――――――――――――――――――――――――――
    您提供的代码:
    ――――――――――――――――――――――――――――
    //添加纪录
    private void button1_Click(object sender, System.EventArgs e)
    {
    myDataRow = myDataTable.NewRow();
    myDataRow[0] = myDataTable.Rows.Count + 2;
    myDataRow[1] = textBox2.Text;
    // myDataRow[2] = textBox3.Text;
    // 如果您的数据表中只有两个字段,则应该将上面一行代码注释掉
    myDataTable.Rows.Add(myDataRow);
    button3_Click(sender,e);

    }
    ――――――――――――――――――――――――――――
    上述代码是往数据表中添加三个字段的值,而数据表中只有两个字段,因此会产生错误。
    至于其他的逻辑错误,请参考acptvb(微软全球技术中心 VB技术支持)上一篇答复。如果还有其他问题,欢迎继续。关于该DateSet的完整示例程序,请参考微软官方网站:
    http://chs.gotdotnet.com/quickstart/winforms/
     — 微软全球技术中心 VB支持中心本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利。具体事项可参见使用条款(http://support.microsoft.com/directory/worldwide/zh-cn/community/terms_chs.asp)。
    为了为您创建更好的讨论环境,请参加我们的用户满意度调查(http://support.microsoft.com/directory/worldwide/zh-cn/community/survey.asp?key=(S,49854782))。
      

  16.   

    多谢大家,这个问题解决了!
    现在给分,请大家到:
    http://www.csdn.net/expert/topic/612/612167.xml?temp=.5718347
    留个名,还有分拿。
    以下是关于这个问题的一些探讨
    =================================
    关于使用DbDataAdapter.Update 方法更新数据库
    [相关资料请参看VS.NET文档中“使用 DataAdapter 和 DataSet 更新数据库”部分]
        DbDataAdapter调用 Update 方法时,DataAdapter 将分析已作出的更改并执行相应的命令(INSERT、UPDATE 或 DELETE)。当 DataAdapter 遇到对 DataRow 的更改时,它将使用 InsertCommand、UpdateCommand 或 DeleteCommand 来处理该更改。这样,您就可以通过在设计时指定命令语法并在可能时通过使用存储过程来尽量提高 ADO.NET 应用程序的性能。在调用 Update 之前,必须显式设置这些命令。如果调用了 Update 但不存在用于特定更新的相应命令(例如,不存在用于已删除行的 DeleteCommand),则将引发异常。
       但是如果 DataTable 映射到单个数据库表或从单个数据库表生成,则可以利用 CommandBuilder 对象自动生成 DataAdapter 的 DeleteCommand、InsertCommand 和 UpdateCommand。为了自动生成命令,必须设置 SelectCommand 属性,这是最低的要求。SelectCommand 所检索的表架构确定自动生成的 INSERT、UPDATE 和 DELETE 语句的语法。如果在自动生成插入、更新或删除命令后修改 SelectCommand 的 CommandText,则可能会发生异常。如果已修改的 SelectCommand.CommandText 所包含的架构信息与自动生成插入、更新或删除命令时所使用的 SelectCommand.CommandText 不一致,则以后对 DataAdapter.Update 方法的调用可能会试图访问 SelectCommand 引用的当前表中已不存在的列,并且会引发异常。可以通过调用 CommandBuilder 的 RefreshSchema 方法来刷新 CommandBuilder 用来自动生成命令的架构信息。
    ---------------------------------------------
    我的问题在于:“如果在自动生成插入、更新或删除命令后修改 SelectCommand 的 CommandText,则可能会发生异常”。这一点请大家注意。
    另外,在给数据表的字段命名时,如果命名不当,也会产生数据更新错误,例如采用“no”这样的字段名(我遇到过这一问题),而这一情况在beta2下很少出现,虽是个小问题,也请大家注意!
    ============================================
    在此感谢大家的参与!在
    http://www.csdn.net/expert/topic/612/612167.xml?temp=.5718347
    还有一百分呢!