Sorunuzu anlamanın yolu, şimdiye kadar manuel değerlerle doldurulmuş bir sütunu olan mevcut bir tablonuz olması ve şimdi (1) bu sütunu bir IDENTITYsütun yapmak ve (2) IDENTITYbaşlangıçların mevcut satırlardaki en son değerden
Öncelikle, oynamak için bazı test verileri:
CREATE TABLE dbo.ident_test (
id int NOT NULL,
xyz varchar(10) NOT NULL,
CONSTRAINT PK_ident_test PRIMARY KEY CLUSTERED (id)
);
INSERT INTO dbo.ident_test (id, xyz)
VALUES (1, 'test'),
(2, 'test'),
(5, 'test'),
(6, 'test'),
(10, 'test'),
(18, 'test'),
(19, 'test'),
(20, 'test');
Amaç, tablonun birincil anahtar sütunu, yani idbir IDENTITYsonraki eklenen kayıt için 21'de başlayacak bir sütun yapmaktır . Bu örnek için sütun xyz, tablonun diğer tüm sütunlarını temsil eder.
Herhangi bir şey yapmadan önce, lütfen bu yazının altındaki uyarıları okuyun.
Öncelikle, bir şeyler ters giderse:
BEGIN TRANSACTION;
Şimdi geçici bir çalışma sütunu ekleyelim id_tempve bu sütunu mevcut idsütunun değerlerine ayarlayalım :
ALTER TABLE dbo.ident_test ADD id_temp int NULL;
UPDATE dbo.ident_test SET id_temp=id;
Daha sonra, mevcut idsütunu bırakmamız gerekiyor ( varolan bir sütuna "ekleyemezsiniz" IDENTITY, sütunu bir olarak oluşturmanız gerekir IDENTITY). Birincil anahtar da gitmelidir, çünkü sütun ona bağlıdır.
ALTER TABLE dbo.ident_test DROP CONSTRAINT PK_ident_test;
ALTER TABLE dbo.ident_test DROP COLUMN id;
... ve sütunu bu kez IDENTITYbirincil anahtarla birlikte bir olarak ekleyin :
ALTER TABLE dbo.ident_test ADD id int IDENTITY(1, 1) NOT NULL;
ALTER TABLE dbo.ident_test ADD CONSTRAINT PK_ident_test PRIMARY KEY CLUSTERED (id);
İşte burada ilginç oluyor. IDENTITY_INSERTTabloda etkinleştirebilirsiniz , yani IDENTITYyeni satırlar eklerken bir sütunun değerlerini manuel olarak tanımlayabilirsiniz (mevcut satırları güncellemezsiniz).
SET IDENTITY_INSERT dbo.ident_test ON;
Bu DELETEkümeyle, tablodaki tüm satırlar, ancak sildiğiniz satırlar OUTPUTtam olarak aynı tablonun içindedir - ancak idsütun için belirli değerlerle (yedek sütundan).
DELETE FROM dbo.ident_test
OUTPUT deleted.id_temp AS id, deleted.xyz
INTO dbo.ident_test (id, xyz);
Tamamlandığında, IDENTITY_INSERTtekrar kapatın.
SET IDENTITY_INSERT dbo.ident_test OFF;
Eklediğimiz geçici sütunu bırakın:
ALTER TABLE dbo.ident_test DROP COLUMN id_temp;
Ve son olarak, IDENTITYsütunu yeniden boyutlandırın , böylece bir sonraki kayıt sütundaki idmevcut en yüksek sayıdan sonra devam edecektir id:
DECLARE @maxid int;
SELECT @maxid=MAX(id) FROM dbo.ident_test;
DBCC CHECKIDENT ("dbo.ident_test", RESEED, @maxid)
Örnek tabloya bakıldığında en yüksek idsayı 20'dir.
SELECT * FROM dbo.ident_test;
Başka bir satır ekleyin ve yeni satırını kontrol edin IDENTITY:
INSERT INTO dbo.ident_test (xyz) VALUES ('New row');
SELECT * FROM dbo.ident_test;
Örnekte, yeni satır olacaktır id=21. Son olarak, memnunsanız işlemi gerçekleştirin:
COMMIT TRANSACTION;
Önemli
Bu önemsiz bir işlem değildir ve bilmeniz gereken birkaç risk taşır.
Bunu özel bir test ortamında yapın. Yedeklemeler var. :)
Kullanmayı seviyorum BEGIN/COMMIT TRANSACTIONçünkü değiştirmenin ortasındayken diğer işlemlerin tabloyla uğraşmasını önler ve bir şeyler ters giderse size her şeyi geri alma imkanı verir. Ancak, işleminizi gerçekleştirmeden önce tablonuza erişmeye çalışan diğer işlemler beklemeye başlar. Büyük bir masanız varsa ve / veya üretim ortamındaysanız bu oldukça kötü olabilir.
OUTPUT .. INTOhedef tablonuzda yabancı anahtar kısıtlamaları veya başımın üstünden hatırlayamadığım başka özellikler varsa çalışmaz. Bunun yerine verileri geçici bir tabloya yükleyebilir ve ardından özgün tabloya geri ekleyebilirsiniz. Bölüm anahtarlamayı kullanabilirsiniz (bölüm kullanmasanız bile).
Bu ifadeleri toplu olarak veya saklı yordamda değil, tek tek çalıştırın.
idBıraktığınız ve yeniden oluşturduğunuz sütuna bağlı olabilecek diğer şeyleri düşünmeye çalışın . Tüm dizinler bırakılmalı ve yeniden oluşturulmalıdır (birincil anahtarda yaptığımız gibi). Önceden yeniden oluşturmanız gereken her dizini ve kısıtlamayı yazmayı unutmayın.
Tablodaki tüm INSERTve DELETEtetikleyicileri devre dışı bırakın .
Tabloyu yeniden oluşturmak bir seçenekse:
Tabloyu yeniden oluşturmak sizin için bir seçenekse, her şey çok daha basittir:
- Boş tabloyu,
idsütun olarak IDENTITY,
IDENTITY_INSERT ONTablo için ayarla ,
- Masayı doldurun,
- Ayarla
IDENTITY_INSERT OFFve
- Kimliği yeniden düzenleyin.
IDENTITY?