简体   繁体   English

更新表语句 - 违反主键约束

[英]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.如果记录存在,我尝试了这个c# 更新,如果记录存在,则插入新记录来更新我的表。

But I run into the exception: "Violation of Primary Key constraint".但我遇到了例外:“违反主键约束”。 Because of this line cmdCount.Parameters.AddWithValue("@local_programs_id", local_programs_id);由于这一行cmdCount.Parameters.AddWithValue("@local_programs_id", local_programs_id); and because there's already a value for local_programs_id in the table并且因为表中已经有local_programs_id的值

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();
            }

You don't have a where filter on your update statement and you are updating the primary key column.您的更新语句中没有 where 过滤器,并且您正在更新主键列。 You're essentially doing你本质上是在做

  1. Check if there is a row with X primary key value检查是否有X主键值的行
  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.您也不应该使用 count(*) 来确定该行是否存在。 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).这只会告诉您该行是否在该时间点存在并且对您的 session 可见(您看不到未提交的事务)。 Most RDBMSs have a MERGE operation you can use for this behaviour, have a look at your RDBMSs docs for it.大多数 RDBMS 都有一个 MERGE 操作,您可以将其用于此行为,请查看您的 RDBMS 文档。 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.或者,乐观地尝试插入语句可能没问题,如果它抛出重复行错误,则执行更新语句。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM