使用ASP.NET MVC更新数据库表失败:行号无法递增
问题分析与解决方案
看起来你遇到的核心问题是调用存储过程更新line_num时,ExecuteNonQuery()始终返回0(说明没有行被更新),而且line_num也没有按预期实现递增。我来帮你拆解可能的问题点,并给出针对性的解决办法:
一、最可能的根源:存储过程的匹配逻辑问题
你代码里调用的是requisition_sp_setstatus0存储过程,但没有给出它的实现代码——这往往是这类问题的关键。请先检查存储过程的UPDATE语句:
- 确认
WHERE子句是否正确使用了@reqNumber和@item_no参数,比如是否存在参数名拼写不一致(SQL不区分大小写,但最好保持和代码一致)、或者参数类型不匹配的情况; - 确认
@reqNumber和@item_no的组合在数据库表中确实存在对应行,如果传入的值在表中找不到,自然不会有行被更新。
举个正确的存储过程示例(假设你的表名为requisition):
CREATE PROCEDURE requisition_sp_setstatus0 @reqNumber VARCHAR(50), @item_no VARCHAR(50), @approve_date DATETIME, @line_num INT AS BEGIN UPDATE requisition SET status = 0, approve_date = @approve_date, line_num = @line_num WHERE reqNumber = @reqNumber AND item_no = @item_no; -- 确保这个条件能精准匹配到目标行 END
二、代码层面的优化点
1. 参数大小匹配问题
你当前的代码没有指定@reqNumber和@item_no的长度,如果存储过程中定义的是VARCHAR(50),但代码里默认的长度可能导致字符串被截断,进而匹配不到数据库中的行。建议显式指定参数大小:
command.Parameters.Add("@reqNumber", SqlDbType.VarChar, 50); // 长度和存储过程保持一致 command.Parameters.Add("@item_no", SqlDbType.VarChar, 50);
2. line_num的递增逻辑是否符合预期
你现在用循环变量i给@line_num赋值,这意味着第一个审批项的line_num是0,第二个是1……如果你的需求是基于数据库中该行已有的line_num值递增(比如原有值是2,审批后变成3),那这个逻辑就错了。此时应该修改存储过程,让它自己处理递增:
-- 修改存储过程中的SET语句 line_num = ISNULL(line_num, 0) + 1 -- 如果line_num可能为NULL,用ISNULL兜底
同时代码里可以移除@line_num参数的相关逻辑,不需要再传入循环变量。
3. 异常处理与调试优化
不要直接throw ex;,这会丢失原始异常的堆栈信息,改成throw;即可。另外,可以捕获ExecuteNonQuery()的返回值,排查具体哪些行没有被更新:
int rowsAffected = command.ExecuteNonQuery(); if (rowsAffected == 0) { // 这里可以加日志或者调试输出,定位问题行 Console.WriteLine($"警告:未找到reqNumber={reqNumbers[i]}、item_no={item_no[i]}的对应记录"); }
4. 资源释放的规范写法
可以把SqlConnection和SqlCommand都放在using块里,不需要手动调用connection.Close(),using会自动帮你释放资源:
public void SetRequisitionStatus0(List<string> reqNumbers, List<string> item_no) { using (SqlConnection connection = new SqlConnection(connectionString)) using (SqlCommand command = new SqlCommand("requisition_sp_setstatus0", connection)) { command.CommandType = CommandType.StoredProcedure; // 显式指定参数大小 command.Parameters.Add("@reqNumber", SqlDbType.VarChar, 50); command.Parameters.Add("@item_no", SqlDbType.VarChar, 50); command.Parameters.Add("@approve_date", SqlDbType.DateTime).Value = DateTime.Now; command.Parameters.Add("@line_num", SqlDbType.Int); try { connection.Open(); for (int i = 0; i < reqNumbers.Count; i++) { command.Parameters["@reqNumber"].Value = reqNumbers[i]; command.Parameters["@item_no"].Value = item_no[i]; command.Parameters["@line_num"].Value = i + 1; // 如果要从1开始计数,改成i+1 int rowsAffected = command.ExecuteNonQuery(); if (rowsAffected == 0) { Console.WriteLine($"未更新行:reqNumber={reqNumbers[i]}, item_no={item_no[i]}"); } } } catch (Exception ex) { // 可以添加日志记录 throw; // 保留原始堆栈信息 } } }
三、排查步骤建议
- 先单独测试存储过程:在SSMS里直接执行
EXEC requisition_sp_setstatus0 '你的测试reqNumber', '测试item_no', GETDATE(), 1,看是否能成功更新行; - 检查传入的
reqNumbers和item_no列表中的值,是否和数据库中的记录完全一致(注意空格、大小写等细节); - 确认数据库连接字符串是正确的,连接的是目标数据库。
内容的提问来源于stack exchange,提问作者user9103273
相关产品推荐
相关产品推荐

