C#学习教程:获取由OleDbCommandBuilder生成的SQL命令问题是我得到异常:“并发冲突:UpdateCommand影响了预期的1条记录中的0条”。我找到了这个错误的解释:因为记录可能在从SELECT语句返回后被修改,但在发出UPDATE或DELETE语句之前,自动生成的UPDATE或DELETE语句包含一个WHERE子句,只指定了该行仅当行值尚未从数据源中删除时才会更新值。如果自动生成的更新尝试更新已删除或不包含在DataSet中找到的原始值的行,则该命令不会影响任何记录,并且会抛出DBConcurrencyException。这意味着自动生成的UPDATE命令影响数据库中的0行。我使用悖论(db-file)数据库,除了我之外没有人改变它。我猜我的程序在某处将同一行更改了两次。我想通过手动执行所有生成的查询来调试我的程序,并找出哪一个不影响任何行(因为实际上我很确定所有更改只进行一次并且错误在其他地方)))。是否可以手动运行自动生成的命令?我的代码太大太复杂,无法在此处发布,但通常它是这样工作的(我制作了一个工作项目并从那里开始)使用System;使用系统数据;使用System.Windows.Forms;使用System.Data.OleDb;namespaceOleDBCommandBuilder{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}privatevoidbutton1_Click(objectsender,EventArgse){stringcs=@"Provider=Microsoft.Jet.OLEDB.4.0;";cs+=@"数据源=C:FOLDER1SPR_KMZ;";cs+=@"扩展属性=Paradox5.x;";OleDbConnection连接=newOleDbConnection();Connection.ConnectionString=cs;尝试{Connection.Open();}catch(Exceptionex){MessageBox.Show("打开数据库时出错!"+ex.Message,"Error",MessageBoxButtons.OK,MessageBoxIcon.Error);环境.退出(0);}stringSQLQuery="SELECT*FROMSPR_KMZWHEREREZ0";数据集SPR_KMZ=new数据集();OleDbDataAdapterDataAdapter=newOleDbDataAdapter();DataAdapter.SelectCommand=newOleDbCommand(SQLQuery,Connection);lder=newOleDbCommandBuilder(DataAdapter);尝试{DataAdapter.Fill(SPR_KMZ);}catch(Exceptionex){System.Windows.Forms.MessageBox.Show(String.Format("Errorn{0}n{1}",ex.Message,SQLQuery));环境.退出(0);}DataRow[]SPR_KMZ_rows=SPR_KMZ.Tables[0].Select("Fkmz=10000912ANDREZ=??1");foreach(DataRowSPR_KMZ_rowinSPR_KMZ_rows){SPR_KMZ_row["DN"]=Convert.ToDateTime("30.12.1899");//26.12.2008SPR_KMZ_row["Price"]=Convert.ToDouble(0);//168,92}DataAdapter.Update(SPR_KMZ);系统.Windows.Forms.MessageBox.Show("成功!");环境.退出(0);}}}PS以前它更新数据库没有并发异常,但经过大量更改(出于调试原因,我评论了“DataAdapter.Update(SPR_KMZ);”行,所以我不知道这个错误是什么时候开始抛出的)PSS我的代码中没有INSERT或DELETE,只有UPDATE...<>我发现了问题所在:如果“DN”字段具有NULL值,那么在更改它之后,自动生成的UPDATE语句将不会影响任何东西,显然是因为“DN”包含在主键中并且命令构建器不希望主键字段具有NULL值(谁曾经))),毫不奇怪这个引擎被称为“Paradox”)))那是为什么CommandBuilder.GetUpdateCommand().CommandText在“DN”字段的where子句中具有此模式:...WHERE((REZ=?)AND(DN=?)AND...可空字段说明如下:...AND((?=1ANDPriceISNULL)OR(Price=?))AND((?=1ANDNmedISNULL)OR(Nmed=?))AND...PSSS嘿,我可能会尝试手动设置UpdateCommand来解决这个问题!)))以下是我如何设法手动设置UpdateCommand,甚至获取每个正在执行的UPDATE命令的SQL代码!(或多或少))在调试时非常有用-我可以看到在DataAdapter.Update(DBDataSet)命令期间无法执行的SQL查询。以上就是C#学习教程:获取OleDbCommandBuilder生成的SQL命令分享的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注——publicvoidUpdate(DataSetDBDataSet){DataAdapter.RowUpdating+=before_update;DataAdapter.Update(DBDataSet);}publicvoidbefore_update(objectsender,EventArgse){//将EventArgs转换为OleDbRowUpdatingEventArgs以便能够使用OleDbCommand属性System.Data.OleDb.OleDbRowUpdatingOventArgs=System.oled_be.OleDbRowUpdatingEventArgs)e;//获取查询模板字符串cmd_txt=oledb_e.Command.CommandText;//在这里修改查询模板来修复它//cmd_txt=cmd_txt.Replace("table_name",""table_name"");//用值填充模板stringcmd_txt_filled=cmd_txt;foreach(System.Data.OleDb.OleDbParameterparinoledb_e.Command.Parameters){stringpar_type=par.DbType.ToString();字符串string_to_replace_with="";if(par.Value.GetType().Name=="DBNull"){string_to_replace_with="NULL";}else{if(par_type=="Int32"){par.Size=4;string_to_replace_with=Convert.ToInt32(par.Value).ToString();}elseif(par_type=="Double"){par.Size=8;string_to_replace_with=Convert.ToDouble(par.Value).ToString().Replace(",",".");}elseif(par_type=="DateTime"){par.Size=8;/*在ParadoxSQL查询中,您不能只将日期指定为字符串,*它将导致不兼容的类型,您必须计算1899年12月30日和所需日期之间的天数,并指定该数字*/string_to_replace_with=DateToParadoxDays(Convert.ToDateTime(par.Value).ToString("dd.MM.yyyy"));}elseif(par_type=="String"){string_to_replace_with='"'+Convert.ToString(par.Value)+'"';}else{//如果字段具有此处未处理的类型,则中断执行System.Diagnostics.Debugger.Break();}}cmd_txt_filled=ReplaceFirst(cmd_txt_filled,"?",string_to_replace_with);}cmd_txt_filled=cmd_txt_filled.Replace("=NULL","ISNULL");//在此处获取查询文本以在数据库管理器中对其进行测试//System.Diagnostics.Debug.WriteLine(cmd_txt_filled);//取消注释以应用修改后的查询模板//oledb_e.Command.CommandText=cmd_txt;//取消注释以简单地运行准备好的更新命令//oledb_e.Command.CommandText=cmd_txt_filled;}publicstringReplaceFirst(stringtext,stringsearch,stringreplace){intpos=text.IndexOf(search);if(pos)本文整理自网络,不代表立场,如涉及侵权,请点击维权联系管理员删除,如需转载请注明出处:
