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

如何在C#中处理数据库主键冲突异常?

Handling Primary Key Conflicts in C# for SQL Server Insertions

Hey there! Let's walk through how to fix the primary key conflict issue in your donor info insertion code, and first let's address a critical security flaw in your current implementation—string concatenation for SQL queries is a huge SQL injection risk. We'll fix that first, then tackle the primary key problem.

First: Fix the SQL Injection Vulnerability

Your current code builds the SQL query by concatenating user input directly, which leaves your database wide open to attacks. Always use parameterized queries instead. Here's how to rewrite your command safely:

using (SqlConnection con = new SqlConnection("YourConnectionString"))
{
    con.Open();
    string insertQuery = @"INSERT INTO donorinfo 
                          (donorid, name, fathersname, age, sex, cnicno, mobileno, 
                           dateofbirth, city, address, eyecolor, bloodgroup, dateofdonation)
                          VALUES (@DonorId, @Name, @FathersName, @Age, @Sex, @CnicNo, 
                                  @MobileNo, @DateOfBirth, @City, @Address, @EyeColor, 
                                  @BloodGroup, @DateOfDonation)";

    using (SqlCommand cmd = new SqlCommand(insertQuery, con))
    {
        // Add parameters with proper types (adjust DbType based on your column types)
        cmd.Parameters.Add("@DonorId", SqlDbType.VarChar).Value = textBox1.Text;
        cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = textBox2.Text;
        cmd.Parameters.Add("@FathersName", SqlDbType.VarChar).Value = textBox3.Text;
        cmd.Parameters.Add("@Age", SqlDbType.Int).Value = int.Parse(textBox4.Text); // Validate input first!
        cmd.Parameters.Add("@Sex", SqlDbType.VarChar).Value = comboBox1.Text;
        cmd.Parameters.Add("@CnicNo", SqlDbType.VarChar).Value = textBox6.Text;
        cmd.Parameters.Add("@MobileNo", SqlDbType.VarChar).Value = textBox7.Text;
        cmd.Parameters.Add("@DateOfBirth", SqlDbType.Date).Value = DateTime.Parse(dateofbirth.Text);
        cmd.Parameters.Add("@City", SqlDbType.VarChar).Value = textBox9.Text;
        cmd.Parameters.Add("@Address", SqlDbType.VarChar).Value = textBox10.Text;
        cmd.Parameters.Add("@EyeColor", SqlDbType.VarChar).Value = comboBox2.Text;
        cmd.Parameters.Add("@BloodGroup", SqlDbType.VarChar).Value = comboBox3.Text;
        cmd.Parameters.Add("@DateOfDonation", SqlDbType.Date).Value = DateTime.Parse(dateofdonation.Text);

        // Conflict handling logic goes here...
    }
}

Note: Always add input validation (e.g., check if textBox4 has a valid integer) to avoid runtime format exceptions.

Solutions for Primary Key Conflicts

Assuming donorid is your primary key, here are the most practical ways to handle duplicate entries:

1. Catch the SQL Exception and Notify the User

SQL Server throws error code 2627 when a primary key violation occurs. You can catch this specific exception and show a user-friendly message:

try
{
    cmd.ExecuteNonQuery();
    MessageBox.Show("Donor info added successfully!");
}
catch (SqlException ex)
{
    if (ex.Number == 2627)
    {
        MessageBox.Show($"Error: A donor with ID {textBox1.Text} already exists.");
    }
    else
    {
        MessageBox.Show($"Database error: {ex.Message}");
    }
}
catch (Exception ex)
{
    MessageBox.Show($"Input error: {ex.Message}");
}

This is straightforward and works well for most cases where you just need to inform the user about duplicates.

2. Use MERGE to Upsert (Insert or Update)

If you want to update the existing donor's info instead of throwing an error when the primary key exists, use the MERGE statement. This lets you define logic for both new and existing records:

string mergeQuery = @"MERGE INTO donorinfo AS Target
                      USING (VALUES (@DonorId, @Name, @FathersName, @Age, @Sex, @CnicNo, 
                                      @MobileNo, @DateOfBirth, @City, @Address, @EyeColor, 
                                      @BloodGroup, @DateOfDonation)) AS Source
                      (donorid, name, fathersname, age, sex, cnicno, mobileno, 
                       dateofbirth, city, address, eyecolor, bloodgroup, dateofdonation)
                      ON Target.donorid = Source.donorid
                      WHEN MATCHED THEN 
                          UPDATE SET 
                              name = Source.name,
                              fathersname = Source.fathersname,
                              age = Source.age,
                              sex = Source.sex,
                              cnicno = Source.cnicno,
                              mobileno = Source.mobileno,
                              dateofbirth = Source.dateofbirth,
                              city = Source.city,
                              address = Source.address,
                              eyecolor = Source.eyecolor,
                              bloodgroup = Source.bloodgroup,
                              dateofdonation = Source.dateofdonation
                      WHEN NOT MATCHED THEN
                          INSERT (donorid, name, fathersname, age, sex, cnicno, mobileno, 
                                  dateofbirth, city, address, eyecolor, bloodgroup, dateofdonation)
                          VALUES (Source.donorid, Source.name, Source.fathersname, Source.age, 
                                  Source.sex, Source.cnicno, Source.mobileno, Source.dateofbirth, 
                                  Source.city, Source.address, Source.eyecolor, Source.bloodgroup, 
                                  Source.dateofdonation);";

// Replace insertQuery with mergeQuery in your SqlCommand, then execute as usual

This is ideal if you want to keep donor records up-to-date when a duplicate ID is submitted.

3. Ignore Duplicates Silently (Use Sparingly)

If you don't need to notify the user or update existing records, you can add WITH (IGNORE_DUP_KEY = ON) to your INSERT statement to skip duplicates without throwing an error:

string insertQuery = @"INSERT INTO donorinfo WITH (IGNORE_DUP_KEY = ON)
                      (donorid, name, fathersname, age, sex, cnicno, mobileno, 
                       dateofbirth, city, address, eyecolor, bloodgroup, dateofdonation)
                      VALUES (@DonorId, @Name, @FathersName, @Age, @Sex, @CnicNo, 
                              @MobileNo, @DateOfBirth, @City, @Address, @EyeColor, 
                              @BloodGroup, @DateOfDonation)";

Use this only if silent failure is acceptable—users won't get any feedback that their entry already exists.

Key Takeaways

  • Never use string concatenation for SQL queries—always use parameterized queries to prevent SQL injection.
  • Pick the conflict handling strategy based on your needs: notify the user, update existing data, or ignore duplicates.
  • Always validate user input to avoid parsing errors (e.g., check if age is a valid integer before converting).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:44:58