Oracle联查仅返回首行:C#代码或数据库表问题排查
排查C# Oracle查询仅返回首行数据的问题
先从最核心的排查步骤开始,一步步定位问题:
第一步:验证SQL语句本身是否正确
首先直接在Oracle客户端(比如SQL Developer)执行你的查询语句:
SELECT * FROM ldhc_accounts la JOIN donors d ON la.donor_id = d.id
如果这里返回的结果只有1行,说明是数据库数据或关联逻辑的问题:
- 检查
ldhc_accounts表中的donor_id是否只关联了donors表中的1条记录(比如其他donor没有对应的account记录) - 如果你需要获取所有donor(不管有没有对应的account),把
JOIN改成LEFT JOIN试试
- 检查
如果SQL工具里返回了3行,那问题就出在C#代码层面,继续往下看。
第二步:排查C#代码的潜在问题
1. 未处理字段为空的情况,导致循环中断
你的代码里直接用Convert.ToInt32、Convert.ToInt64转换字段值,如果某一行的某个字段是NULL或者非数字格式,会直接抛出异常,导致while(reader.Read())循环提前终止,只添加了第一条数据。
修复方式:添加DBNull判断,同时捕获异常排查问题:
public List<Donor> Get() { List<Donor> donors = new List<Donor>(); string query = "SELECT * FROM ldhc_accounts la JOIN donors d ON la.donor_id = d.id"; // 使用using自动释放数据库资源,避免连接泄漏 using (OracleConnection conn = new OracleConnection(你的连接字符串)) { conn.Open(); using (OracleCommand cmd = new OracleCommand(query, conn)) { using (OracleDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { try { Donor d = new Donor(); // 处理字段为空的情况 d.DonorId = reader["id"] is DBNull ? 0 : Convert.ToInt32(reader["id"]); d.FName = reader["fname"] is DBNull ? string.Empty : reader["fname"].ToString(); d.LName = reader["lname"] is DBNull ? string.Empty : reader["lname"].ToString(); d.Address = reader["address"] is DBNull ? string.Empty : reader["address"].ToString(); d.City = reader["city"] is DBNull ? string.Empty : reader["city"].ToString(); d.Province = reader["province"] is DBNull ? string.Empty : reader["province"].ToString(); d.Phone = reader["phone"] is DBNull ? 0 : Convert.ToInt64(reader["phone"]); d.LdhcDonorId = reader["donor_id"] is DBNull ? 0 : Convert.ToInt32(reader["donor_id"]); d.TableId = reader["table_id"] is DBNull ? 0 : Convert.ToInt32(reader["table_id"]); d.DonorCredit = reader["account_number"] is DBNull ? 0 : Convert.ToInt64(reader["account_number"]); d.DonorCCV = reader["ccv"] is DBNull ? 0 : Convert.ToInt32(reader["ccv"]); d.DonorExpMonth = reader["expiry_month"] is DBNull ? 0 : Convert.ToInt32(reader["expiry_month"]); d.DonorExpYear = reader["expiry_year"] is DBNull ? 0 : Convert.ToInt32(reader["expiry_year"]); d.Donor_Amt = reader["amount"] is DBNull ? 0 : Convert.ToInt32(reader["amount"]); donors.Add(d); } catch (Exception ex) { // 输出异常信息,定位哪一行出问题 System.Diagnostics.Debug.WriteLine($"读取第{donors.Count+1}行出错:{ex.Message}"); } } } } } return donors; }
2. 数据库连接未正确释放
你的原代码里直接使用全局的conn对象,如果之前的操作没有正确关闭连接,可能会导致Reader读取异常。用using语句可以确保连接、命令、Reader在使用后自动释放,避免资源泄漏问题。
3. WebForm拼接HTML的小优化
虽然这不是导致仅返回首行的直接原因,但用StringBuilder拼接HTML比直接拼接InnerHtml效率更高,也能避免潜在的字符串拼接问题:
protected void get_donors_btn_Click(object sender, EventArgs e) { List<Donor> d = a_oracle.Get(); StringBuilder sb = new StringBuilder(); foreach(Donor item in d) { sb.AppendFormat("<li>{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12} {13}</li>", item.DonorId, item.FName, item.LName, item.Address, item.City, item.Province, item.Phone, item.LdhcDonorId, item.TableId, item.DonorCredit, item.DonorCCV, item.DonorExpMonth, item.DonorExpYear, item.Donor_Amt); } get_donors.InnerHtml = sb.ToString(); }
按照上面的步骤一步步排查,应该能快速定位并解决问题。
内容的提问来源于stack exchange,提问作者Jessica Wong
相关产品推荐
相关产品推荐

