700分求援,说到做到!!关于Update的“并发冲突”!!! Have a look at this article at MS china.http://www.microsoft.com/china/msdn/library/dnbda/html/BOAGag.asp 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 错误的本质原因是因为你UPDATE的语句中的记录和数据库中的记录不一致,所以数据库不让你修改。你的“情况简介”对我们来说没有什么价值,请把SQL语句给我看。你的SQL语句是参数化的,还是手工写的?只要你给我更多的信息,我就可以帮你搞定,因为我们这段时间经常处理“Update并发冲突” 兄弟,我也碰到过这个问题,比较难解决。比如说,新增加了一条记录,然后又对这条记录进行了修改、删除等操作,那么就会出现这个问题。我这能把ds导出到xml文件中,修改行的状态。还有批量更新也可能会违反约束,头疼啊! 数据的约束或完整性(try use trigger) Update并发冲突并不难解决,我已经研究的很透了.违反约束的问题是另一回事,你为什么会头疼呢,违反约束就应该不能更新呀,如果你想强行更新,我也有办法,以前有人问过,我解答过. aspcn(飞刀) :你是ASPCN的飞刀老大? 从你的错误信息看,有可能是由于数据的更新顺序引起的,另外,不知道相应的UpdateCommand、InsertCommand 和DeleteCommand是使用SqlCommandBuilder自动生成的,还是自己写的,这一点很重要,这很可能是问题所在。下面是理由,希望对你有所帮助。 调用 Update时,SqlDataAdapter 根据 DataSet 中配置的索引顺序为每一行检查 RowState 属性,并迭代执行所需的 INSERT、UPDATE 或 DELETE 语句。由于 DataTable 中行的排序,插入、修改和删除命令执行的顺序是不确定的。可是,以何种顺序向数据源发送DataSet的更改非常重要。在这里,会不会是已经更新某行的主键值,在这之后update企图删除已经更新了的行。因为你的表是自动编号的,所以我觉得原因不会是顺序问题,但也不能排除。下面两个办法都试一试:1 如果更新语句不是自动生成的,在 Update 语句的 WHERE 子句中指定的参数应该是 对应列的Original 值。这一点很重要,因为 Current 值可能是被修改过的,这就有可能不匹配数据源中的值。2 你可以使用 DataTable 的 Select 方法来返回具有特定 RowState 的 DataRow 数组,然后将返回的 DataRow 数组传递到 Update 方法来处理已修改的行。这样,通过指定要更新的行的子集就可以控制插入、更新和删除的顺序。 下面代码首先处理表中已删除的行,然后处理已更新的行,然后处理已插入的行。DataTable updTable = custDS.Tables["Customers"];custDA.Update(updTable.Select(null, null, DataViewRowState.Deleted));custDA.Update(updTable.Select(null, null, DataViewRowState.ModifiedCurrent));custDA.Update(updTable.Select(null, null, DataViewRowState.Added)); dy_2000_abc(芝麻开门) 程序不是多用户。不过我在三个类里面用数据层的相同的adapter填充了相同的dataset ,当然接下来的INSERT、DELETE等也都是用同样的东西!关于COMMAND,我是用VS自动生成的存储过程,没有参数,但有排序(在存储过程的SQL脚本中)!BY THE WAY,THERE IS NO "关系" in my db !!! Elsa_Fent(宪兵队) :我在MSDN中看到一文说与IDENTITY列有关要怎么改一下数据集里的表,加一列负数编号之类,我没看仔细,因为觉得太烦!是与这有关么?现在可以肯定的是,与我的程充代码无关!因我在VS中又NEW了一个PROJECT(只有最简单的窗体),用同一数据库,同样是自动生成STORED PROCEDURE,删除行时,有同样异常出现!!! 我猜你就是用的自动生成的语句,自动生成的语句远比你想的复杂,数据库要判断记录集中的Original值是否等于数据库中的当前值.如果不等,就报并发错误.你的表中的主键是什么IDENTITY还是GUID? 请把你的STORED PROCEDURE给我们看看.给你个例子,我的表名是TestTable,只有三个字段,ID是主健整型,fname varchar(50),degintime datetimepublic DataSet UpdateData(){ SqlCommand comm = new SqlCommand("select * from TestTable", cn); SqlDataAdapter ad = new SqlDataAdapter(); ad.SelectCommand = comm; ad.MissingSchemaAction = MissingSchemaAction.AddWithKey; ad.Fill(ds, "testtable"); DataRow dr = ds.Tables[0].Rows[0]; dr["fname"] = "Tom"; SqlCommand updateComm = null; SqlDataAdapter ad2 = null; SqlParameter param1 = null; SqlParameter param2 = null; SqlParameter param3 = null; try { ad2 = new SqlDataAdapter(); updateComm = new SqlCommand("update testtable set fname=@newName where id=@id and begintime=@begintime", cn); param2 = new SqlParameter("@newName", SqlDbType.NVarChar, 50, "fname"); updateComm.Parameters.Add(param2); param1 = new SqlParameter("@id", SqlDbType.Int, 4,"id"); param1.SourceVersion = DataRowVersion.Original; updateComm.Parameters.Add(param1); param3 = new SqlParameter("@begintime", SqlDbType.DateTime, 8, "begintime"); param1.SourceVersion = DataRowVersion.Original; updateComm.Parameters.Add(param3); ad2.UpdateCommand = updateComm; ad2.Update(ds.Tables["testtable"]); } catch(Exception e) { string error = e.Message; } return ds;} 我全都重新做了一遍,把数据库中一个字段TimeIntoDB给删除了,原来这个字段我给了一个公式,就是问题所在,因为现在已经完全正常了!公式是:GETDATE(),这可能就是所谓的时间戳吧?!这样的话,三个版本的值比起来肯定就会不同了! C# GDI+ 画图问题 高分请教 问个字符串处理的问题!!!!!!!!!!!!!1 在水晶报表里! 问一下序列化和反序列化的作用! 紧急求助,50分 Visual Studio 2005中,Web项目的工具箱中不能加入ActiveX控件? 一个大dataset问题 .net中文件隐式上传和下载(急急急) 几句唠叨话!发泻一下! 还是System.NullReferenceException,Label.Content 怎么才能让MDI里面父窗口的按钮可以改变全部或者某个指定的子窗口控件的属性呢? 怎样使一个窗口由小变大
你的“情况简介”对我们来说没有什么价值,请把SQL语句给我看。你的SQL语句是参数化的,还是手工写的?只要你给我更多的信息,我就可以帮你搞定,因为我们这段时间经常处理“Update并发冲突”
违反约束的问题是另一回事,你为什么会头疼呢,违反约束就应该不能更新呀,如果你想强行更新,我也有办法,以前有人问过,我解答过.
调用 Update时,SqlDataAdapter 根据 DataSet 中配置的索引顺序为每一行检查 RowState 属性,并迭代执行所需的 INSERT、UPDATE 或 DELETE 语句。由于 DataTable 中行的排序,插入、修改和删除命令执行的顺序是不确定的。可是,以何种顺序向数据源发送DataSet的更改非常重要。在这里,会不会是已经更新某行的主键值,在这之后update企图删除已经更新了的行。因为你的表是自动编号的,所以我觉得原因不会是顺序问题,但也不能排除。下面两个办法都试一试:
1 如果更新语句不是自动生成的,在 Update 语句的 WHERE 子句中指定的参数应该是 对应列的Original 值。这一点很重要,因为 Current 值可能是被修改过的,这就有可能不匹配数据源中的值。
2 你可以使用 DataTable 的 Select 方法来返回具有特定 RowState 的 DataRow 数组,然后将返回的 DataRow 数组传递到 Update 方法来处理已修改的行。这样,通过指定要更新的行的子集就可以控制插入、更新和删除的顺序。
下面代码首先处理表中已删除的行,然后处理已更新的行,然后处理已插入的行。
DataTable updTable = custDS.Tables["Customers"];
custDA.Update(updTable.Select(null, null, DataViewRowState.Deleted));
custDA.Update(updTable.Select(null, null, DataViewRowState.ModifiedCurrent));
custDA.Update(updTable.Select(null, null, DataViewRowState.Added));
程序不是多用户。不过我在三个类里面用数据层的相同的adapter填充了相同的dataset ,当然接下来的INSERT、DELETE等也都是用同样的东西!关于COMMAND,我是用VS自动生成的存储过程,没有参数,但有排序(在存储过程的SQL脚本中)!BY THE WAY,THERE IS NO "关系" in my db !!!
我在MSDN中看到一文说与IDENTITY列有关要怎么改一下数据集里的表,加一列负数编号之类,我没看仔细,因为觉得太烦!是与这有关么?现在可以肯定的是,与我的程充代码无关!
因我在VS中又NEW了一个PROJECT(只有最简单的窗体),用同一数据库,同样是自动生成STORED PROCEDURE,删除行时,有同样异常出现!!!
你的表中的主键是什么IDENTITY还是GUID? 请把你的STORED PROCEDURE给我们看看.
给你个例子,我的表名是TestTable,只有三个字段,ID是主健整型,fname varchar(50),degintime datetimepublic DataSet UpdateData()
{
SqlCommand comm = new SqlCommand("select * from TestTable", cn);
SqlDataAdapter ad = new SqlDataAdapter();
ad.SelectCommand = comm;
ad.MissingSchemaAction = MissingSchemaAction.AddWithKey;
ad.Fill(ds, "testtable");
DataRow dr = ds.Tables[0].Rows[0];
dr["fname"] = "Tom";
SqlCommand updateComm = null;
SqlDataAdapter ad2 = null;
SqlParameter param1 = null;
SqlParameter param2 = null;
SqlParameter param3 = null;
try
{
ad2 = new SqlDataAdapter();
updateComm = new SqlCommand("update testtable set fname=@newName where id=@id and begintime=@begintime", cn);
param2 = new SqlParameter("@newName", SqlDbType.NVarChar, 50, "fname");
updateComm.Parameters.Add(param2); param1 = new SqlParameter("@id", SqlDbType.Int, 4,"id");
param1.SourceVersion = DataRowVersion.Original;
updateComm.Parameters.Add(param1); param3 = new SqlParameter("@begintime", SqlDbType.DateTime, 8, "begintime");
param1.SourceVersion = DataRowVersion.Original;
updateComm.Parameters.Add(param3); ad2.UpdateCommand = updateComm;
ad2.Update(ds.Tables["testtable"]);
}
catch(Exception e)
{
string error = e.Message;
}
return ds;
}