Vik0809
Vik0809

Reputation: 379

update table statement - Violation of Primary Key constraint

I tried this c# update if record exists else insert new record to update my table, if records exists.

But I run into the exception: "Violation of Primary Key constraint". Because of this line cmdCount.Parameters.AddWithValue("@local_programs_id", local_programs_id); and because there's already a value for local_programs_id in the table

What have I done wrong?

Thanks a lot.

SqlConnection connection = new SqlConnection(sqlConnection_String);
            

            SqlCommand cmdCount = new SqlCommand("SELECT count(*) FROM " + datenbankname + " WHERE local_programs_id = @local_programs_id" , connection);
            cmdCount.Parameters.AddWithValue("@local_programs_id", local_programs_id);

            connection.Open();

            int count = (int)cmdCount.ExecuteScalar();
            Console.WriteLine("count1 " + count);
         

            if (count > 0)
            {
                SqlCommand updateCommand = new SqlCommand("UPDATE " + datenbankname + 
                    " SET local_programs_Id = @local_programs_Id, " +
                    "program_name = @program_name, " +
                    "publisher_name = @publisher_name, " +
                    "program_version = @program_version, " +
                    "install_dir = @install_dir, " +
                    "uninstall_dir = @uninstall_dir, " +
                    "inserted_at = @inserted_at, " +
                    "direct_link_available = @direct_link_available", connection);

                updateCommand.Parameters.AddWithValue("@local_programs_Id", local_programs_id);
                updateCommand.Parameters.AddWithValue("@program_name", program_names);
                updateCommand.Parameters.AddWithValue("@publisher_name", publisher_names);
                updateCommand.Parameters.AddWithValue("@program_version", program_version);
                updateCommand.Parameters.AddWithValue("@install_dir", install_location);
                updateCommand.Parameters.AddWithValue("@uninstall_dir", uninstall_location);
                updateCommand.Parameters.AddWithValue("@inserted_at", DateTime.Now);
                updateCommand.Parameters.AddWithValue("@direct_link_available", direct_link_available);

                int rowsUpdated = updateCommand.ExecuteNonQuery();
                Console.WriteLine("rowsUpdated " + rowsUpdated);
            }
            else
            {

                Console.WriteLine("inserted1 ");
            
                string query = "INSERT INTO " + datenbankname + " (local_programs_Id, program_name, publisher_name, program_version, install_dir,  uninstall_dir, inserted_at)";
                query += " VALUES (@local_programs_Id, @program_name, @publisher_name, @program_version, @install_dir, @uninstall_dir, @inserted_at)";

                SqlCommand insertCommand = new SqlCommand(query, connection);
                
                insertCommand.Parameters.AddWithValue("@local_programs_Id", local_programs_id);
                insertCommand.Parameters.AddWithValue("@program_name", program_names);
                insertCommand.Parameters.AddWithValue("@publisher_name", publisher_names);
                insertCommand.Parameters.AddWithValue("@program_version", program_version);
                insertCommand.Parameters.AddWithValue("@install_dir", install_location);
                insertCommand.Parameters.AddWithValue("@uninstall_dir", uninstall_location);
                insertCommand.Parameters.AddWithValue("@inserted_at", DateTime.Now);

                int rowsInserted = insertCommand.ExecuteNonQuery();
            }

Upvotes: 0

Views: 897

Answers (1)

Andrew Sayer
Andrew Sayer

Reputation: 2336

You don't have a where filter on your update statement and you are updating the primary key column. You're essentially doing

  1. Check if there is a row with X primary key value
  2. If there is then update every row to have that primary key value.
  3. If not then insert.

You should not be updating the primary key ever, even in your case where it isn't supposed to be changing. There are lots of annoying behaviour that could come from this, one that springs to mind is where this primary key is referenced in a foreign key in another table - this update statement would put locks on the other table (potentially a full table lock if it's not indexed).

You also should not be using a count(*) to determine whether the row exists. This will only tell you if the row exists at that point in time and is visible to your session (you can't see non-committed transactions). Most RDBMSs have a MERGE operation you can use for this behaviour, have a look at your RDBMSs docs for it. Alternatively, it might be okay to optimistically try the insert statement and if it throws a duplicate row error then you do the update statement.

Upvotes: 1

Related Questions