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

C# Windows Form删除按钮无法正确执行SQL命令问题

问题分析与修复:Windows Form中ADO.NET删除数据库记录失败

核心问题与修复代码

你的代码最关键的错误是没有执行SQL命令——缺少SqlCommand.ExecuteNonQuery()调用,导致即使参数和语句正确,数据库也不会收到执行请求。同时还有参数类型转换、事务使用的细节问题,以下是修复后的完整代码:

private void buttonViewPersonDelete_Click(object sender, EventArgs e)
{
    // 先判断是否有选中行,避免空引用异常
    if (dataGridViewPerson.CurrentCell == null)
    {
        MessageBox.Show("请先选择要删除的记录", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        return;
    }

    string sSqlConnection = GetDBConnectionString("dbConnectionString");

    DialogResult result = MessageBox.Show("确定要删除选中的数据吗?", "删除确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
    if (result != DialogResult.OK)
    {
        return;
    }

    using (SqlConnection sqlConn = new SqlConnection(sSqlConnection))
    {
        sqlConn.Open();
        // 使用using包裹事务,自动处理释放
        using (SqlTransaction sqlTrans = sqlConn.BeginTransaction())
        {
            try
            {
                using (SqlCommand sqlCmd = new SqlCommand("DELETE FROM dbo.Person WHERE iPersonID = @PersonID", sqlConn, sqlTrans))
                {
                    DataGridViewRow selectedRow = dataGridViewPerson.CurrentCell.OwningRow;
                    // 显式转换为int,避免字符串转int的隐式转换问题
                    int personID = Convert.ToInt32(selectedRow.Cells[0].Value);
                    sqlCmd.Parameters.Add("@PersonID", SqlDbType.Int).Value = personID;

                    // 关键:执行SQL命令
                    int affectedRows = sqlCmd.ExecuteNonQuery();
                    if (affectedRows == 0)
                    {
                        MessageBox.Show("未找到对应记录,删除失败", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        sqlTrans.Rollback();
                        return;
                    }

                    sqlTrans.Commit();
                    MessageBox.Show("删除成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"删除失败:{ex.Message}", ex.GetType().Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
                try
                {
                    sqlTrans.Rollback();
                }
                catch (Exception ex2)
                {
                    MessageBox.Show($"回滚事务失败:{ex2.Message}", ex2.GetType().Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            finally
            {
                UpdateDataGridViewStatus();
                // using包裹的SqlConnection会自动关闭,这里可以省略Close()
            }
        }
    }
}

关键错误点说明

  • 未执行SQL命令:原代码仅设置了CommandText和参数,但没有调用ExecuteNonQuery(),这是命令不执行的根本原因。该方法会返回受影响的行数,可用来验证是否成功删除记录。
  • 参数类型不匹配:原代码将字符串sPersonID直接赋值给SqlDbType.Int类型的参数,虽然.NET可能会隐式转换,但显式转换为int类型更安全,避免潜在的格式转换异常。
  • 缺少选中行判断:未判断dataGridViewPerson.CurrentCell是否为null,若用户未选中任何行,会触发空引用异常。
  • 事务使用不够严谨:原代码未用using包裹事务,改为using后可自动释放事务资源,避免内存泄漏。
  • 冗余的Connection.Close():using块包裹的SqlConnection会在块结束时自动关闭连接,无需手动调用Close()。

额外优化建议

  • 可以通过dataGridViewPerson.SelectedRows来获取选中行,更直观(需确保DataGridView的MultiSelect属性为false,符合单条删除场景):
    if (dataGridViewPerson.SelectedRows.Count == 0)
    {
        MessageBox.Show("请选择要删除的记录", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        return;
    }
    DataGridViewRow selectedRow = dataGridViewPerson.SelectedRows[0];
    
  • 捕获特定异常(如FormatException、SqlException),可以更精准地提示错误类型,比如ID格式错误、数据库连接失败等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 19:09:31