输入错误凭证时因DataSet中表不存在引发的登录异常问题求助
解决登录验证时"Cannot find table 1"异常的问题
这个问题的核心原因一目了然:当输入错误凭证时,你的存储过程executivelogin只返回了一个数据表(也就是错误信息表),但你的代码不管登录结果如何,都直接尝试访问ds.Tables[1]——这自然会抛出找不到表的异常。而正确凭证时存储过程返回了两个表,所以代码能正常执行。
修复方案
我们需要在访问ds.Tables[1]之前,先判断这个表是否存在(或者判断DataSet里的表数量是否足够),再执行后续逻辑。下面是修改后的代码:
[HttpPost] public ActionResult ExecutiveLogin(int? exuserid, string exusername) { SqlCommand cmd = new SqlCommand("executivelogin", cn); cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@executiveid", exuserid); cmd.Parameters.AddWithValue("@executivetypename", exusername); cn.Open(); DataSet ds = new DataSet(); SqlDataAdapter da = new SqlDataAdapter(); da.SelectCommand = cmd; da.Fill(ds); // 先确保表0存在再命名 if (ds.Tables.Count > 0) { ds.Tables[0].TableName = "Error Message"; } var message = ds.Tables[0].Rows[0].ItemArray[0]; List<Customer> query = null; // 关键:先检查是否存在表1,再处理客户数据 if (ds.Tables.Count > 1) { ds.Tables[1].TableName = "Customer Data"; var Customerdata = (from DataRow row in ds.Tables[1].Rows select new Customer { CustomerName = row["CustomerName"].ToString(), Type = row["type"].ToString(), }); query = Customerdata.ToList(); ViewBag.custdata = query; } // 统一设置错误信息(根据message内容区分成功/失败提示) ViewBag.errormessage = message; cn.Close(); // 原代码遗漏了关闭连接,会导致数据库连接泄漏 return View(); }
额外优化建议
- 数据库连接管理:原代码打开连接后未关闭,容易造成连接泄漏。更稳妥的方式是使用
using语句自动管理连接生命周期:using (SqlConnection cn = new SqlConnection("你的数据库连接字符串")) { // 所有数据库操作写在这里,using块结束时会自动关闭并释放连接 } - 存储过程逻辑对齐:也可以调整存储过程,让它在验证失败时返回一个空的第二个表,这样代码无需做判断,但上面的修复方案更独立,不依赖存储过程的修改。
- 空值校验:
exuserid是可空类型,建议先判断是否有有效值再传入参数,避免潜在的SQL参数异常。
内容的提问来源于stack exchange,提问作者Developer




