C#操作MySQL执行sum查询无匹配数据触发InvalidCastException如何解决
报错原因与修复方案
根因分析
SQL聚合函数SUM()在WHERE条件匹配不到任何行时,不会返回空结果集,而是返回1行值为NULL的结果,所以你加的rdr2.HasRows判断始终为真,会进入读取逻辑。此时读取到的total字段是DBNull类型,无法直接通过GetInt32转换为整数,因此抛出类型转换异常。
修复方案
方案1:修改原有DataReader逻辑
新增DBNull判断,同时改用参数化查询避免SQL注入风险,修正后代码如下:
MySqlCommand cmdsumpayment = new MySqlCommand("SELECT sum(amount) as 'total' from payments where unit_id = @unitId AND deleted_at IS NULL", conn); // 参数化查询避免SQL注入 cmdsumpayment.Parameters.AddWithValue("@unitId", UNITID); using (MySqlDataReader rdr2 = cmdsumpayment.ExecuteReader()) { if (rdr2.Read()) { if (!rdr2.IsDBNull("total")) { TOTALPAYMENTS = rdr2.GetInt32("total"); } else { // 无匹配记录时赋值默认值0 TOTALPAYMENTS = 0; // 如需提示可在此处加 MessageBox.Show("nothing found"); } } } // using会自动释放DataReader资源,不需要手动Close
方案2(更推荐):使用ExecuteScalar读取单值
因为你只需要读取单个聚合结果,用ExecuteScalar比DataReader更简洁,同时可以直接在SQL层面处理NULL值:
MySqlCommand cmdsumpayment = new MySqlCommand("SELECT IFNULL(sum(amount), 0) from payments where unit_id = @unitId AND deleted_at IS NULL", conn); cmdsumpayment.Parameters.AddWithValue("@unitId", UNITID); // IFNULL会将SUM返回的NULL转为0,保证返回值始终是数字 TOTALPAYMENTS = Convert.ToInt32(cmdsumpayment.ExecuteScalar());
这里用到的MySQL的IFNULL函数,会判断第一个参数是否为NULL,是则返回第二个参数的默认值,不需要在代码中额外做空判断。
内容的提问来源于stack exchange,提问作者Arsalan Ahmadi
相关产品推荐
相关产品推荐

