記錄是我數據庫中的一個表,'Code'是主鍵。sql - 在兩條記錄之間插入
代碼 - >1000-1001-1002-1003-1004 ...
如果1002刪除1000-1001-1003-1004
如果有一個新的記錄搜索 '代碼',並找到POS機,例如 1000-1001-1003-1004
和新紀錄的主鍵將1002
。
但是兩個記錄主鍵之間的pos不會是1005
。
我該怎麼做?
記錄是我數據庫中的一個表,'Code'是主鍵。sql - 在兩條記錄之間插入
代碼 - >1000-1001-1002-1003-1004 ...
如果1002刪除1000-1001-1003-1004
如果有一個新的記錄搜索 '代碼',並找到POS機,例如 1000-1001-1003-1004
和新紀錄的主鍵將1002
。
但是兩個記錄主鍵之間的pos不會是1005
。
我該怎麼做?
代碼主鍵列也是一個標識列,在每次插入新記錄時自動增加。你應該保持原樣。不要重複使用主鍵,因爲它可能會影響數據庫的完整性。如果可能,儘量不要刪除記錄,可以在表中添加一列,通過將它們標記爲活動或非活動狀態來跟蹤每條記錄的狀態。
顯然你使用一個自然鍵作爲你的表的主鍵。這沒關係,當然你可以刪除這樣的記錄,然後重新使用該密鑰。一個例子是員工表,關鍵是員工號碼,可能會重複使用一段時間。
只有您使用SQL Server的自動增量功能,您可以爲基於ID的表執行自動增量功能,但不能使用自然鍵。
在SQL Server中,這種類型的自動增量列稱爲IDENTITY。刪除該屬性並關心管理密鑰代碼。
當使用IDENTITY
列時,不能簡單地在記錄之間插入記錄,IDENTITY
表示該密鑰的值由數據庫自動生成。
但是,我認爲你的問題不是關於插入新記錄,而是你不能告訴結果集中一行的索引,如果你刪除了該集合中的一行,並且該行下面的id現在是分段的。
那麼,正如在評論和其他答案中指出的那樣,重用主鍵通常是一個壞主意,你應該讓自己的邏輯儘可能與鍵的值無關。
這就是說,當然如果你有一個主鍵有一個數字類型,按順序排列可以在很多情況下有意義,但是如果你想告訴一個集合內某行的位置而不使用指數本身我建議你使用ROW_NUMBER():
這裏是一個simple sample聲明表,刪除一行,仍表現出無需復位或重複使用的主鍵是集內的每一行的正確指數(行號):
DECLARE @RowOrderTest TABLE (ID INT PRIMARY KEY IDENTITY(1,1), Value NVARCHAR(15));
INSERT INTO @RowOrderTest (Value)
SELECT 'dummy'
UNION ALL
SELECT 'dummy'
UNION ALL
SELECT 'dummy'
UNION ALL
SELECT 'dummy'
UNION ALL
SELECT 'dummy'
UNION ALL
SELECT 'dummy'
UNION ALL
SELECT 'dummy'
UNION ALL
SELECT 'dummy'
DELETE @RowOrderTest WHERE ID = 5
SELECT ID, Value, ROW_NUMBER() OVER (ORDER BY ID) FROM @RowOrderTest
如果您確實需要使用(事先)已知鍵值插入一行,不使用IDENTITY
-columns所有,或您的行插入
後關掉使用SET IDENTITY_INSERT dbo.[Table] ON
前SET IDENTITY_INSERT dbo.[Table] OFF
自動行爲,在個別情況下,我需要插入一個值,違背了身份,我做這樣的事情:
SET IDENTITY_INSERT dbo.[Table] ON --Allow insert of specific ID values
INSERT INTO dbo.[Table] ...
SET IDENTITY_INSERT dbo.[Table] OFF --Revert to auto-generated ID values
您需要一個結構,因此您需要手動跟蹤序列中的「打開間隙」。所以,當插入時刪除和刪除值時插入值。 –
你不想重新使用主鍵。 SQL Server通過保持差距來做正確的事情。如果你想要你指定的行爲,你必須寫一個觸發器。 –
我認爲你需要解釋*爲什麼*你需要這樣做。我的猜測是,你或者是)當你應該更新它時刪除一條記錄,或者b。)爲一個反模式的標識分配一個語義值。 –