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

DataGridView循环查询重复记录异常 删除重复行后仍触发重复告警

问题原因
  • 核心逻辑错误:mukerrer方法的校验逻辑只会保留最后一行的校验结果,后序行的校验状态会直接覆盖前面的结果;同时你使用的全局durum变量没有在方法开头重置状态,上次校验留下的false值会一直残留,就算删除重复行后也不会自动更新。
  • 空行触发异常:默认开启AllowUserToAddRows属性的DataGridView会在末尾自带一个空的待输入行,遍历到该行时读取barkod_no会触发空引用异常,方法直接中断,durum会保持上次的false状态,导致一直弹出重复警告。
  • 存在SQL注入风险:拼接SQL字符串的写法容易被注入攻击,特殊格式下还会触发语法错误。
  • 资源泄漏风险:SqlDataReader未主动释放,频繁开关数据库连接效率低下。
修复方案

1. 重写校验方法

bool mukerrer()
{
    // 初始默认无重复
    bool hasDuplicate = false;
    for (int i = 0; i < dataGridView1.Rows.Count; i++)
    {
        // 跳过空的新行和值为空的行
        if (dataGridView1.Rows[i].IsNewRow || dataGridView1.Rows[i].Cells["barkod_no"].Value == null)
            continue;
        
        long barkodNo = Int64.Parse(dataGridView1.Rows[i].Cells["barkod_no"].Value.ToString());
        using (SqlCommand komut = new SqlCommand("SELECT COUNT(1) FROM STOKLAR WHERE barkod_no = @barkodNo", baglanti))
        {
            komut.Parameters.AddWithValue("@barkodNo", barkodNo);
            baglanti.Open();
            int count = Convert.ToInt32(komut.ExecuteScalar());
            baglanti.Close();
            if (count > 0)
            {
                hasDuplicate = true;
                // 发现重复直接跳出循环,无需校验剩余行
                break;
            }
        }
    }
    // 有重复返回false,无重复返回true,和原有逻辑对齐
    return !hasDuplicate;
}

2. 修正提交按钮逻辑

private void simpleButton1_Click(object sender, EventArgs e)
{
    bool durum = mukerrer();
    if (durum == true)
    {
        // 用事务保证所有数据要么全插入成功要么全回滚,避免部分插入的脏数据问题
        baglanti.Open();
        SqlTransaction tran = baglanti.BeginTransaction();
        try
        {
            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                if (dataGridView1.Rows[i].IsNewRow || dataGridView1.Rows[i].Cells["barkod_no"].Value == null)
                    continue;
                
                SqlCommand komut = new SqlCommand("insert into STOKLAR(barkod_no,toplam_paket_no,paket_no,raf_id,create_date) values (@barkod_no,@toplam_paket_no,@paket_no,@raf_id,@create_date)", baglanti, tran);
                komut.Parameters.AddWithValue("@barkod_no", Int64.Parse(dataGridView1.Rows[i].Cells["barkod_no"].Value.ToString()));
                komut.Parameters.AddWithValue("@toplam_paket_no", int.Parse(dataGridView1.Rows[i].Cells["toplam_paket_no"].Value.ToString()));
                komut.Parameters.AddWithValue("@paket_no", int.Parse(dataGridView1.Rows[i].Cells["paket_no"].Value.ToString()));
                komut.Parameters.AddWithValue("@raf_id", dataGridView1.Rows[i].Cells["raf_id"].Value.ToString());
                komut.Parameters.AddWithValue("@create_date", dataGridView1.Rows[i].Cells["create_date"].Value);
                komut.ExecuteNonQuery();
            }
            tran.Commit();
            textRaf.Text = "";
            MessageBox.Show("Kayıtlar Eklenmiştir.");
            this.ActiveControl = textRaf;
        }
        catch (Exception ex)
        {
            tran.Rollback();
            MessageBox.Show("Kayıt ekleme hatası: " + ex.Message);
        }
        finally
        {
            baglanti.Close();
        }
    }
    else
    {
        MessageBox.Show("Sistemde kayıtlı olan barkod var!", "Bilgi", MessageBoxButtons.OK, MessageBoxIcon.Warning);
    }      
}

额外优化建议

  • 可以把全局的baglanti对象改成方法内创建,用完即释放,避免连接长时间占用导致异常。
  • 给STOKLAR表的barkod_no字段加唯一索引,就算校验逻辑漏判,数据库也会阻止重复数据插入,双重保障。

内容的提问来源于stack exchange,提问作者Sinem Hür

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 04:45:04