C#操作MySQL如何判断输入ID已存在并阻止重复插入数据
实现方案
你现有代码有几个致命问题,导致重复ID判断完全不生效:
- 逻辑顺序完全错误:先执行INSERT写入数据,再做ID重复判断,此时重复数据已经落库,判断没有任何意义
- 查重逻辑无效:代码中
cust_ID变量从未从数据库查询赋值,和用户输入的id对比完全得不到正确结果 - 字符串拼接构造SQL存在严重SQL注入风险,输入内容带单引号等特殊字符时会直接执行失败
- 数据库连接、命令没有做资源释放,异常场景下会持续占用数据库连接
前置准备(必须做)
首先给main表的cust_ID列加唯一索引,从数据库层面彻底禁止重复ID写入,避免高并发下先查后插的竞态问题,执行下面的SQL即可:
ALTER TABLE main ADD UNIQUE INDEX uk_cust_id (cust_ID);
实现逻辑
- 先对用户输入做基础合法性校验,避免非数字输入导致类型转换报错
- 数据库连接打开后,首先查询当前输入ID是否已存在于
cust_ID列 - 若ID已存在,直接弹出
ID Already exists提示,终止后续插入逻辑 - 若ID不存在,通过参数化SQL执行插入操作,成功后弹出插入成功提示
- 所有数据库对象用
using语句包裹,自动完成资源释放,无需手动调用Close() - 增加唯一键冲突异常捕获作为兜底,极端并发场景下也能正确提示重复
修正后的完整代码
void Button2Click(object sender, EventArgs e) { // 输入合法性校验 if (!int.TryParse(textBox1.Text, out int id)) { MessageBox.Show("请输入有效的数字ID"); return; } if (!int.TryParse(textBox3.Text, out int totalItems)) { MessageBox.Show("请输入有效的总条目数"); return; } string name = textBox2.Text.Trim(); if (string.IsNullOrWhiteSpace(name)) { MessageBox.Show("姓名不能为空"); return; } string connStr = "server=localhost;database=csharp_database;username=root;password=nfreal-yt10;"; // using自动释放连接资源,出作用域自动关闭连接 using (MySqlConnection con = new MySqlConnection(connStr)) { try { con.Open(); // 第一步:ID查重 string checkSql = "SELECT COUNT(1) FROM main WHERE cust_ID = @custId"; using (MySqlCommand checkCmd = new MySqlCommand(checkSql, con)) { checkCmd.Parameters.AddWithValue("@custId", id); int existCount = Convert.ToInt32(checkCmd.ExecuteScalar()); if (existCount > 0) { MessageBox.Show("ID Already exists"); return; } } // 第二步:执行插入 string insertSql = "INSERT INTO main (cust_ID, cust_name, cust_total_items) VALUES (@custId, @custName, @totalItems)"; using (MySqlCommand insertCmd = new MySqlCommand(insertSql, con)) { insertCmd.Parameters.AddWithValue("@custId", id); insertCmd.Parameters.AddWithValue("@custName", name); insertCmd.Parameters.AddWithValue("@totalItems", totalItems); insertCmd.ExecuteNonQuery(); MessageBox.Show("Inserted Successfully"); } } catch (Exception ex) { // 兜底捕获唯一键冲突异常 if (ex.Message.Contains("Duplicate entry") && ex.Message.Contains("uk_cust_id")) { MessageBox.Show("ID Already exists"); } else { MessageBox.Show($"操作失败:{ex.Message}"); } } } }
补充说明
- 参数化写法彻底避免SQL注入问题,即使用户输入的姓名里带单引号、SQL关键字等特殊字符,也不会出现执行错误或数据被恶意篡改的问题
- 异常捕获里的唯一键冲突判断是最后一道防线,哪怕多个用户同时提交相同ID,数据库层面的唯一约束会拦住重复写入,代码也会给出正确提示
- 不需要手动判断
sql_cmd != null,用using创建的命令对象只要进入对应作用域就一定是合法实例,原代码里的这个判断没有实际意义
内容的提问来源于stack exchange,提问作者Pythonic User
相关产品推荐
相关产品推荐

