You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改C#代码以显示指定卡号的所有数据库交易记录?

修改C#代码以返回指定卡号的所有交易记录

原代码存在的核心问题

  • 循环读取记录时,每读取一条就直接用return退出方法,导致只能返回第一条匹配的交易记录
  • 直接拼接SQL字符串,存在SQL注入风险,恶意输入可能破坏数据库或窃取数据
  • 判断字段为空的逻辑错误:数据库中的NULL在SqlDataReader中对应DBNull,直接调用GetString()会抛出异常,不能用== null判断

修改后的完整代码

private static string extratoOperacao(string numeroCartao)
{
    // 改用参数化查询传递卡号,避免SQL注入
    return getExtrato(numeroCartao);
}

private static string getExtrato(string numeroCartao)
{
    // 用StringBuilder累加所有交易记录,比直接字符串拼接更高效
    var resultado = new StringBuilder();
    using (var cn = new SqlConnection("Data Source=MAD-PC-023\\SQLEXPRESS;Database=bank;Trusted_Connection=True;"))
    {
        cn.Open();
        // 参数化SQL语句,避免注入风险
        var query = "SELECT CardNumber, Deposit, Withdraw, DataHora FROM MoveInfo WHERE CardNumber = @CardNumber";
        using (var cmd = new SqlCommand(query, cn))
        {
            // 添加参数并赋值
            cmd.Parameters.AddWithValue("@CardNumber", numeroCartao);
            var reader = cmd.ExecuteReader();
            
            // 遍历所有匹配的交易记录
            while (reader.Read())
            {
                var cartaoNumero = reader.GetString(0);
                var dataHora = reader.GetDateTime(3);
                
                if (reader.IsDBNull(1))
                {
                    // Deposit为空,判定为取款操作
                    var valorLevantamento = reader.GetDecimal(2);
                    resultado.AppendLine($"  O cartão nº {cartaoNumero} levantou: {valorLevantamento} às: {dataHora}");
                }
                else
                {
                    // Deposit不为空,判定为存款操作
                    var valorDeposito = reader.GetDecimal(1);
                    resultado.AppendLine($"  O cartão nº {cartaoNumero} depositou: {valorDeposito} euros às: {dataHora}");
                }
            }
        }
    }
    // 无记录时返回提示,否则返回所有拼接好的交易内容
    return resultado.Length == 0 ? "Nenhuma transação encontrada para este cartão." : resultado.ToString();
}

关键修改说明

  1. 替换字符串拼接为参数化查询:通过@CardNumber参数传递卡号,彻底规避SQL注入风险
  2. 用StringBuilder收集所有记录:避免每次拼接字符串产生新对象,同时能完整保留所有交易记录
  3. 修正空值判断逻辑:使用reader.IsDBNull(index)判断字段是否为数据库NULL,避免抛出异常
  4. 遍历所有匹配记录:移除循环内的return语句,确保所有记录都被读取并拼接
  5. 改用数值类型读取金额:假设Deposit和Withdraw是数值类型(如Decimal),用GetDecimal()读取比GetString()更合理,避免类型转换问题

内容的提问来源于stack exchange,提问作者user20571251

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 06:01:36