C#中SqlDataReader循环仅返回第一条数据问题求助
问题分析与修复方案
核心问题
你的getExtrato方法里,while循环读取第一行数据后就直接执行return,方法直接结束,所以永远只能返回第一行,后续行根本没机会处理。
其他需要修复的问题
- SQL注入风险:直接用字符串拼接生成SQL语句,极易被恶意利用,必须改用参数化查询。
- 空值判断错误:数据库中的空值是
DBNull,用reader.GetString(1) == null判断会抛出异常,应该用reader.IsDBNull(1)来检查。
修改后的完整代码
private static string getExtrato(SqlCommand cmd) { StringBuilder result = new StringBuilder(); using (var cn = new SqlConnection(@"Data Source=MAD-PC-023\SQLEXPRESS;Database=bank;Trusted_Connection=True;")) { cn.Open(); cmd.Connection = cn; var reader = cmd.ExecuteReader(); while (reader.Read()) { string cardNumber = reader.GetString(0); DateTime dataHora = reader.GetDateTime(3); if (reader.IsDBNull(1)) { // 存款为空,说明是取款操作 decimal withdraw = reader.GetDecimal(2); result.AppendLine($" O cartão nº {cardNumber} levantou: {withdraw} euros às: {dataHora}"); } else { // 存款不为空,说明是存款操作 decimal deposit = reader.GetDecimal(1); result.AppendLine($" O cartão nº {cardNumber} depositou: {deposit} euros às: {dataHora}"); } } return result.ToString(); } } private static string extratoOperacao(string numeroCartao) { using (var cmd = new SqlCommand(@"SELECT CardNumber, Deposit, Withdraw, DataHora FROM MoveInfo WHERE CardNumber = @CardNumber")) { cmd.Parameters.Add("@CardNumber", SqlDbType.VarChar).Value = numeroCartao; return getExtrato(cmd); } }
关键修改说明
- 用
StringBuilder收集所有行的内容,循环内只做追加操作,循环结束后再返回完整结果。 - 将SQL语句改为参数化查询,避免SQL注入,同时提升查询性能。
- 用
reader.IsDBNull()正确判断数据库空值,并且假设Deposit和Withdraw是数值类型(比如decimal),改用GetDecimal更合理,避免字符串转换的问题。 - 调整
getExtrato的参数为SqlCommand,方便传递参数化的命令对象。
内容的提问来源于stack exchange,提问作者user20571251
相关产品推荐
相关产品推荐

