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

C# WinForm提交费用数据时fees表重复插入两条相同记录问题

问题背景
  • 开发技术栈:C# WinForm
  • 数据库信息:库名School,其中fees表包含stu_id、fees两个字段
  • 故障表现:前端提交费用信息后,数据库会新增2条完全相同的记录,不符合预期的单条插入逻辑,其他窗体编写的同类插入逻辑未出现该异常。

数据库重复记录问题截图

问题复现代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace SchoolManagementSystem
{
    public partial class Fees : Form
    {
        public Fees()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SqlConnection con = new SqlConnection(@"Data Source=DRAGON\SQLEXPRESS;Initial Catalog=School;Integrated Security=True;");
            con.Open();

            try
            {
                string str = " INSERT INTO fees VALUES('" + textBox1.Text + "','" + textBox2.Text + "')";

                SqlCommand cmd = new SqlCommand(str, con);
                cmd.ExecuteNonQuery();

                SqlDataReader dr = cmd.ExecuteReader();
                if (dr.Read())
                {
                    MessageBox.Show("Your Fees Submitted..");
                    this.Hide();
                    Home obj2 = new Home();
                    obj2.ShowDialog();
                }
                this.Close();
            }
            catch (SqlException excep)
            {
                MessageBox.Show(excep.Message);
            }
            con.Close();

        }
        private void textBox1_MouseLeave(object sender, EventArgs e)
        {
            textBox2.Text = "";
            SqlConnection con = new SqlConnection(@"Data Source=DRAGON\SQLEXPRESS;Initial Catalog=School;Integrated Security=True;");
            con.Open();
            if (textBox1.Text != "")
            {
                try
                {
                    string getCust = "select name,standard,medium from student where std_id=" + Convert.ToInt32(textBox1.Text) + " ;";

                    SqlCommand cmd = new SqlCommand(getCust, con);
                    SqlDataReader dr;
                    dr = cmd.ExecuteReader();
                    if (dr.Read())
                    {
                        label9.Text = dr.GetValue(0).ToString();
                        label6.Text = dr.GetValue(1).ToString();
                        label7.Text = dr.GetValue(2).ToString();
                    }
                    else
                    {
                        MessageBox.Show("Sorry '" + textBox1.Text + "' This Registration Id is Invalid, Please Insert Correct Id");
                        textBox1.Text = "";
                        textBox2.Text = "";
                    }
                }
                catch (SqlException excep)
                {
                    MessageBox.Show(excep.Message);
                }
                con.Close();
            }
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }

        private void Fees_Load(object sender, EventArgs e)
        {

        }
    }
}
故障根因

重复插入的核心原因是同一条INSERT语句被执行了两次:

  1. 第一次执行:调用cmd.ExecuteNonQuery()时,已经向fees表插入了1条记录
  2. 第二次执行:后续又对同一个绑定了INSERT语句的cmd对象调用cmd.ExecuteReader(),该方法会再次执行绑定的SQL语句,导致第二次插入重复记录。

额外存在的逻辑错误:INSERT属于增删改操作,执行后不会返回结果集,后续的dr.Read()判断本身没有实际意义,永远不会进入写好的成功提示分支。
同时代码还存在SQL注入风险、数据库资源未可靠释放的隐患。

修复方案
  1. 删除多余的cmd.ExecuteReader()相关逻辑,INSERT操作仅需调用ExecuteNonQuery()即可,通过该方法的返回值(受影响行数)判断是否插入成功
  2. 建议改用参数化查询避免SQL注入,使用using块自动释放数据库连接、命令等非托管资源,避免资源泄漏。

修复后的提交按钮点击事件参考代码:

private void button1_Click(object sender, EventArgs e)
{
    // using块会在代码执行结束后自动释放连接资源,不需要手动调用Close
    using (SqlConnection con = new SqlConnection(@"Data Source=DRAGON\SQLEXPRESS;Initial Catalog=School;Integrated Security=True;"))
    {
        try
        {
            con.Open();
            // 用参数化写法替代SQL拼接,避免注入风险,明确指定插入字段避免表结构变动后出错
            string str = "INSERT INTO fees(stu_id, fees) VALUES(@stuId, @fees)";
            using (SqlCommand cmd = new SqlCommand(str, con))
            {
                // 给参数赋值,可根据字段实际类型指定SqlDbType提升查询效率
                cmd.Parameters.AddWithValue("@stuId", textBox1.Text.Trim());
                cmd.Parameters.AddWithValue("@fees", textBox2.Text.Trim());
                // ExecuteNonQuery返回受影响的行数,等于1代表插入成功
                int affectRows = cmd.ExecuteNonQuery();
                if (affectRows > 0)
                {
                    MessageBox.Show("费用提交成功");
                    this.Hide();
                    Home obj2 = new Home();
                    obj2.ShowDialog();
                }
            }
            this.Close();
        }
        catch (SqlException excep)
        {
            MessageBox.Show(excep.Message);
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 04:36:14