GridView与数据库更新问题求助:球员进球数更新代码报错
这个报错的核心原因很明确:你的查询语句没有返回任何数据,却直接尝试访问Rows[0]。我们来一步步拆解代码里的问题,逐个修复:
问题1:数据适配器未使用带参数的命令
你创建了sqlCmd并添加了参数,但初始化OleDbDataAdapter时直接用了原始的queryStr,完全没用到这个带参数的命令。这导致实际执行的查询是不带参数的空查询,自然查不到对应UserID的球员记录,数据集里没有行,访问Rows[0]就会触发报错。
问题2:DataRow索引访问错误
你的查询语句是SELECT Achievement FROM SoccerAchievements WHERE UserID=@AchNums,返回的结果集只有1列(Achievement),但你用了row[3]——这不仅会在查询到数据时触发索引越界错误,逻辑上也完全不对,应该改成row[0]或者更直观的row["Achievement"]。
问题3:错误解析参数字符串
int.Parse("@AchNums")这行完全是逻辑错误,@AchNums是参数名,不是用户输入的数值,你应该取文本框里的实际输入值来转换。
问题4:更新命令未正确设置
你复用了之前的sqlCmd,但没有更新它的CommandText为更新语句;而且Achievement是数值类型,不需要用单引号包裹,否则会引发类型转换错误。
问题5:未判断查询结果是否为空
在访问Rows[0]之前,必须先检查数据集里的表是否有行,避免空索引的错误。
修复后的完整C#代码
string connectionStr = @"Provider=Microsoft.Jet.OleDb.4.0;Data Source=|DataDirectory|\SoccerDataBase.mdb"; using (OleDbConnection sqlCon = new OleDbConnection(connectionStr)) { sqlCon.Open(); // 获取Footer里的文本框控件 TextBox achNumsTxt = SoccerTable.FooterRow.FindControl("AchNums") as TextBox; if (achNumsTxt == null || string.IsNullOrWhiteSpace(achNumsTxt.Text)) { // 可添加用户提示:比如"请输入球员ID" return; } string targetUserId = achNumsTxt.Text.Trim(); // 1. 查询目标球员当前进球数(使用带参数的命令) string queryStr = "SELECT Achievement FROM SoccerAchievements WHERE UserID=@UserID"; OleDbCommand queryCmd = new OleDbCommand(queryStr, sqlCon); queryCmd.Parameters.AddWithValue("@UserID", targetUserId); OleDbDataAdapter dataAdapt = new OleDbDataAdapter(queryCmd); DataSet ds = new DataSet(); dataAdapt.Fill(ds, "SoccerAchievement"); // 2. 检查是否查询到有效记录 if (ds.Tables["SoccerAchievement"].Rows.Count == 0) { // 可添加用户提示:比如"未找到该球员" return; } // 3. 计算更新后的进球数(这里默认进球数+1,若要自定义加球数可新增文本框) DataRow row = ds.Tables["SoccerAchievement"].Rows[0]; int currentAchievement = int.Parse(row["Achievement"].ToString()); int newAchievement = currentAchievement + 1; // 4. 执行更新操作 string updateQuery = "UPDATE SoccerAchievements SET Achievement= @NewAchievement WHERE UserID= @UserID"; OleDbCommand updateCmd = new OleDbCommand(updateQuery, sqlCon); updateCmd.Parameters.AddWithValue("@NewAchievement", newAchievement); updateCmd.Parameters.AddWithValue("@UserID", targetUserId); int affectedRows = updateCmd.ExecuteNonQuery(); if (affectedRows > 0) { // 更新成功后重新绑定GridView,刷新页面数据 SoccerTable.DataBind(); } }
额外的GridView优化建议
你的Footer模板只有一个文本框,逻辑上容易混淆。如果需要让用户自定义增加的进球数,建议修改Footer模板:
<FooterTemplate> 球员ID:<asp:TextBox ID="UserIDTxt" runat="server"></asp:TextBox> 增加进球数:<asp:TextBox ID="AddGoalsTxt" runat="server"></asp:TextBox> </FooterTemplate>
这样用户可以清晰输入球员ID和要添加的进球数,代码里只需新增获取AddGoalsTxt值的逻辑即可。
内容的提问来源于stack exchange,提问作者Alex

