使用C#和存储过程更新Access数据库无效果问题排查
问题原因及解决办法
核心问题是OleDb访问Access存储过程时不识别参数名称,仅按参数传入顺序匹配存储过程中参数的出现顺序。
你的存储过程里,参数出现的顺序是@FirstName(SET子句中先使用)→ @ID(WHERE子句后使用),但C#代码中先添加的是@ID参数,再添加@FirstName,导致参数值错位:存储过程中@FirstName拿到的是ID的值,@ID拿到的是FirstName的值,WHERE条件无法匹配到任何行,因此ExecuteNonQuery()返回0,数据库无更新。
解决步骤
调整C#代码中参数添加的顺序,与存储过程中参数出现的顺序一致:
public void updateTest(int ID,string FirstName) { OleDbCommand TestCmd = new OleDbCommand("UpdateTest", this.objConn); TestCmd.CommandType = CommandType.StoredProcedure; OleDbParameter ObjParam; // 先添加存储过程中先出现的@FirstName参数 ObjParam = TestCmd.Parameters.Add("@FirstName", OleDbType.BSTR); ObjParam.Direction = ParameterDirection.Input; ObjParam.Value = FirstName; // 再添加后出现的@ID参数 ObjParam = TestCmd.Parameters.Add("@ID", OleDbType.Numeric); ObjParam.Direction = ParameterDirection.Input; ObjParam.Value = ID; try { this.objConn.Open(); var result = TestCmd.ExecuteNonQuery(); } catch (Exception ex) { // 优化异常处理:抛出带原始异常的新异常,便于排查问题 throw new Exception("更新Test表失败", ex); } finally { this.objConn.Close(); } }
额外优化建议
- 异常处理优化:原代码中仅包装异常却未抛出,导致无法感知异常发生,建议改为抛出或记录日志。
- 资源自动释放:使用
using语句自动管理OleDbCommand的生命周期,避免资源泄漏:
public void updateTest(int ID,string FirstName) { using (OleDbCommand TestCmd = new OleDbCommand("UpdateTest", this.objConn)) { TestCmd.CommandType = CommandType.StoredProcedure; OleDbParameter ObjParam; ObjParam = TestCmd.Parameters.Add("@FirstName", OleDbType.BSTR); ObjParam.Direction = ParameterDirection.Input; ObjParam.Value = FirstName; ObjParam = TestCmd.Parameters.Add("@ID", OleDbType.Numeric); ObjParam.Direction = ParameterDirection.Input; ObjParam.Value = ID; try { this.objConn.Open(); var result = TestCmd.ExecuteNonQuery(); } catch (Exception ex) { throw new Exception("更新Test表失败", ex); } finally { this.objConn.Close(); } } }
内容的提问来源于stack exchange,提问作者Moshe Yalovsky
相关产品推荐
相关产品推荐

