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

C#报错无法将DBNull对象转换为其他类型 求排查修复方案

错误原因
  • 核心触发原因:读取数据库字段时未做DBNull判断。数据库中字段存NULL值时,SqlDataReader读取到的结果是DBNull.Value类型,该类型无法直接通过Convert.ToInt32转换为int,直接调用转换就会抛出「对象无法从DBNull转换为其他类型」异常。
  • 隐藏语法错误:操作Stotal_table的UPDATE语句多写了一个多余逗号,语句为Update Stotal_table set MiniBar=@MiniBar, where Item=@Item,执行时会触发SQL语法错误。
  • 资源泄漏风险:SqlConnection、SqlCommand等数据库对象未做资源自动释放处理,若执行过程中抛出异常,数据库连接不会被主动关闭,会持续占用连接池资源。
  • 前置校验缺失:未判断cbox2.SelectedItem是否为空,若下拉框无选中项直接调用ToString()会触发空引用异常;定义的连接字符串变量未实际使用,存在冗余代码。
  • 规范问题:直接在master系统库中创建业务表,master是SQL Server存储系统元数据、配置信息的系统库,不适合存放业务数据。
修复方案
  1. 所有从SqlDataReader读取的字段,先判断是否为DBNull.Value,如果是NULL值则赋默认值0,再做类型转换。
  2. 删掉UPDATE语句中SET子句末尾多余的逗号,修正SQL语法。
  3. 所有数据库操作对象用using块包裹,执行结束后自动释放资源,无需手动调用Close(),异常场景下也能安全释放连接。
  4. 增加前置入参校验,操作前先确认下拉框选中项、数值输入值合法;抽离重复的连接创建逻辑,删除冗余代码。
  5. 建议后续单独创建业务数据库存放两张业务表,不要占用master系统库。
修复后完整代码
// 前置入参校验
if (cbox2.SelectedItem == null)
{
    MessageBox.Show("请先选择对应物料项");
    return;
}
int addQty = (int)Nd2.Value;
string connStr = @"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=master;Integrated Security=True;Application Name=Aung";

// 处理Mini_table表逻辑
using (SqlConnection connection = new SqlConnection(connStr))
{
    connection.Open();
    SqlCommand cmdCount = new SqlCommand("SELECT COUNT(*) FROM Mini_table WHERE Item = @Item", connection);
    cmdCount.Parameters.AddWithValue("@Item", cbox2.SelectedItem.ToString());
    int count = (int)cmdCount.ExecuteScalar();
    int currentQty = 0;
    if (count > 0)
    {
        SqlCommand command = new SqlCommand("SELECT Qty FROM Mini_table WHERE Item = @Item", connection);
        command.Parameters.AddWithValue("@Item", cbox2.SelectedItem.ToString());
        using (SqlDataReader reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                // 核心修复:判断DBNull后再转换
                currentQty = reader["Qty"] == DBNull.Value ? 0 : Convert.ToInt32(reader["Qty"]);
            }
        }
        SqlCommand updatecmd = new SqlCommand("Update Mini_table set Qty=@Qty, Date=@Date where Item=@Item", connection);
        updatecmd.Parameters.AddWithValue("@Qty", currentQty + addQty);
        updatecmd.Parameters.AddWithValue("@Date", DateTime.Now);
        updatecmd.Parameters.AddWithValue("@Item", cbox2.SelectedItem.ToString());
        updatecmd.ExecuteNonQuery();
        dgv2.DataSource = null;
        MessageBox.Show("Update successfully");
    }
    else
    {
        SqlCommand insertcmd = new SqlCommand("insert into Mini_table(Item,Qty,Date)values(@Item,@Qty,@Date)", connection);
        insertcmd.Parameters.AddWithValue("@Item", cbox2.SelectedItem.ToString());
        insertcmd.Parameters.AddWithValue("@Qty", addQty);
        insertcmd.Parameters.AddWithValue("@Date", DateTime.Now);
        insertcmd.ExecuteNonQuery();
        dgv2.DataSource = null;
        MessageBox.Show("Insert successfully");
    }
}

// 处理Stotal_table表逻辑
using (SqlConnection connection = new SqlConnection(connStr))
{
    connection.Open();
    SqlCommand cmdCount = new SqlCommand("SELECT COUNT(*) FROM Stotal_table WHERE Item = @Item", connection);
    cmdCount.Parameters.AddWithValue("@Item", cbox2.SelectedItem.ToString());
    int count = (int)cmdCount.ExecuteScalar();
    int currentMiniBar = 0;
    if (count > 0)
    {
        SqlCommand command = new SqlCommand("SELECT MiniBar FROM Stotal_table WHERE Item = @Item", connection);
        command.Parameters.AddWithValue("@Item", cbox2.SelectedItem.ToString());
        using (SqlDataReader reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                // 核心修复:判断DBNull后再转换
                currentMiniBar = reader["MiniBar"] == DBNull.Value ? 0 : Convert.ToInt32(reader["MiniBar"]);
            }
        }
        // 修复:删除@MiniBar后多余的逗号
        SqlCommand updatecmd = new SqlCommand("Update Stotal_table set MiniBar=@MiniBar where Item=@Item", connection);
        updatecmd.Parameters.AddWithValue("@MiniBar", currentMiniBar + addQty);
        updatecmd.Parameters.AddWithValue("@Item", cbox2.SelectedItem.ToString());
        updatecmd.ExecuteNonQuery();
    }
    else
    {
        SqlCommand insertcmd = new SqlCommand("insert into Stotal_table(Item,MiniBar)values(@Item,@MiniBar)", connection);
        insertcmd.Parameters.AddWithValue("@Item", cbox2.SelectedItem.ToString());
        insertcmd.Parameters.AddWithValue("@MiniBar", addQty);
        insertcmd.ExecuteNonQuery();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 00:01:05