技术问询:如何通过用户输入参数查询SQL数据并执行数值相乘运算
代码问题分析与修正
你的代码存在多个关键问题,直接运行大概率会报错或引发安全风险,下面逐一说明并给出修复方案:
核心问题点
- SQL注入漏洞:直接将用户输入的
Subject和Level拼接到SQL语句中,恶意用户可通过构造输入篡改SQL逻辑,窃取或破坏数据。 - 未检查DataReader数据状态:执行
ExecuteReader()后直接读取列值,若查询无匹配数据,会抛出索引越界或无效操作异常。 - 列名读取错误:代码中
NumS读取的是Subject_name列,但SQL查询的是Students列,会导致类型转换失败。 - 整数除法截断:
(Price*NumS)/100用整数除法,结果含小数时会被直接截断,无法保留精确计算结果。 - 资源未释放:
SqlCommand和SqlDataReader未用using语句,可能导致数据库连接资源泄漏。
修复后的代码
// 用参数化查询避免SQL注入,using语句自动释放资源 using (SqlCommand cmd = new SqlCommand("select Charges, Students from Subs where Subject_name=@Subject and Level=@Level", con)) { // 添加参数绑定用户输入 cmd.Parameters.AddWithValue("@Subject", Subject); cmd.Parameters.AddWithValue("@Level", Level); using (var reader = cmd.ExecuteReader()) { // 先确认是否查询到数据 if (reader.Read()) { // 读取正确的列值 int price = Convert.ToInt32(reader["Charges"]); int studentCount = Convert.ToInt32(reader["Students"]); // 用decimal处理金额计算,避免浮点精度丢失 decimal finalAmount = (price * studentCount) / 100m; status = finalAmount.ToString("F2") + "$"; // 保留两位小数,如"3.60$" } else { // 处理无匹配数据的情况 status = "未找到对应记录"; } } }
额外提示
- 若
Charges或Students字段可能为NULL,需先判断是否为空再转换,示例:int price = reader.IsDBNull(reader.GetOrdinal("Charges")) ? 0 : Convert.ToInt32(reader["Charges"]); - 金额计算优先用
decimal类型,比float/double更精准,避免精度丢失问题。
内容的提问来源于stack exchange,提问作者sendhelpcodingishard
相关产品推荐
相关产品推荐

