2014-04-15 61 views
0

我有一個ASP.Net Web窗體應用程序,它使用SqlCommand並使用ExecuteNonQuery方法將新記錄(請求)插入到SQL Server表中。該表具有爲Identity Specification = Yes,Identity Increment 1,Identity Seed 1設置的單個主鍵(int id)。該應用程序已運行多年。大約一個月前,數據庫從物理服務器移動到虛擬服務器,沒有任何明顯的問題。數據庫正在SQL Server 10.50.1617.0上運行。在具有標識列的SQL Server中重複記錄

最近,用戶報告創建了大約90個請求,但無法找到它們。當我檢查請求表時,我只能找到在過去幾天爲她創建的一個請求。請求表上的最高ID是5404.作爲一個實驗,我讓她創建了一個新的請求。我期待它創建一個新的ID爲5405,但它實際上創建了一個ID爲2975.我讓她創建另一個請求,並在ID爲2975的第二個請求與另一個請求重寫。我創建了一個測試請求,它創建了一個在身份證5405。什麼可能導致這種情況?

這裏是C#中插入:

 string sql = "insert into requests (end_user_email) values (@email)"; 
     SqlConnection cn = new SqlConnection(_cnString); 

     SqlCommand cmdIns = new SqlCommand(sql, cn); 
     cmdIns.Parameters.Add("@email", SqlDbType.NVarChar); 
     cmdIns.Parameters["@email"].Value = email; 

     cmdIns.Connection.Open(); 
     cmdIns.ExecuteNonQuery(); 
+0

您所描述的內容與您在此處顯示的代碼沒有出現。我建議你有一個觸發器來查找插入,並在表上進行更新。 – paqogomez

+0

它實際上重新創建了2975還是隻是更新它?它是如何移動的?聽起來像一個問題與身份屬性可能或她可能做一個更新,而不是插入。這是發生在所有請求還是隻是這些? – jensendp

+0

我會建議與你的DBA聽起來像是當DataBase被移動,一些腳本不運行時,這不是一個代碼問題,它是一個數據庫相關的問題 – MethodMan

回答

3

你的表名是不是有模式修飾(例如,dbo.requests)。我懷疑你的數據庫中有兩個不同的表,名稱相同。一個由dbo模式擁有;另外通過您的默認架構。當前連接的憑據定義

  1. 探頭的命名空間指定名稱的默認模式下oject:

    SQL Server名稱解析的工作不合格引用如下。如果找到一個,則該對象將解析該引用。否則...

  2. dbo模式下探測指定名稱的對象的命名空間。如果找到一個,則該對象將解析該引用。否則...

  3. 如果對象是名稱以sp_開頭的存儲過程,則對上述步驟#1和#2中的master數據庫執行名稱空間的其他探測。

  4. 最後,如果引用未解析,名稱解析失敗。

您的用戶使用一個默認架構連接使用的憑據和解決到一個名爲requests即要麼通過該模式或dbo擁有的表。

你,而另一方面,正在使用的憑證與另一默認模式,找到一個不同表具有相同的名稱,您的默認模式或dbo要麼擁有。

每個人都應該始終架構限定對象的引用,用於兩方面的原因:

  • 性能。兩個名稱空間探測器用於查找您可能想要的性能方面所需的對象。
  • 此外,涉及非限定引用的執行計劃可能無法緩存,從而導致額外的重新編譯。

  • 最後,你或其他人會在某個時候在腳下開槍自殺。通常,一方執行存儲過程的一個版本而另一方執行不同的版本。歡鬧隨之而來 - 「它適用於我的機器!」。更好的是,當不同的人碰到同一張表的不同版本時,會收到關於缺失列的隨機錯誤。

無論其...

這不是聞所未聞:-)爲identity列有identity屬性的值,走出與各種原因的數據同步。

因此,如果您已經排除了同一個表的兩個不同的口味,你會希望你的DBA運行DBCC CHECKIDENT對陣表來獲取表的identity櫃檯後面同步與在高水位標記表。

  • DBCC CHECKIDENT({表名},noreseed)兩者上identity計數器的表,並在表中的當前高水位標記的當前值

    報告。

  • DBCC CHECKIDENT({表名},補種)

    重播的identity計數器到表比擬的高水位標記。

+0

夢幻般的答案+1 – paqogomez