簡體   English   中英

更新表語句 - 違反主鍵約束

[英]update table statement - Violation of Primary Key constraint

如果記錄存在,我嘗試了這個c# 更新,如果記錄存在,則插入新記錄來更新我的表。

但我遇到了例外:“違反主鍵約束”。 由於這一行cmdCount.Parameters.AddWithValue("@local_programs_id", local_programs_id); 並且因為表中已經有local_programs_id的值

我做錯了什么?

非常感謝。

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

您的更新語句中沒有 where 過濾器,並且您正在更新主鍵列。 你本質上是在做

  1. 檢查是否有X主鍵值的行
  2. 如果有則更新每一行以具有該主鍵值。
  3. 如果沒有則插入。

您永遠不應該更新主鍵,即使在您不應該更改主鍵的情況下也是如此。 這可能會產生很多煩人的行為,我想到的是這個主鍵在另一個表的外鍵中引用的地方——這個更新語句會在另一個表上加鎖(如果它是,則可能是一個完整的表鎖)未編入索引)。

您也不應該使用 count(*) 來確定該行是否存在。 這只會告訴您該行是否在該時間點存在並且對您的 session 可見(您看不到未提交的事務)。 大多數 RDBMS 都有一個 MERGE 操作,您可以將其用於此行為,請查看您的 RDBMS 文檔。 或者,樂觀地嘗試插入語句可能沒問題,如果它拋出重復行錯誤,則執行更新語句。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM