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 IDENTITY
sütun yapmak ve (2) IDENTITY
baş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 id
bir IDENTITY
sonraki 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_temp
ve bu sütunu mevcut id
sü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 id
sü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 IDENTITY
birincil 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_INSERT
Tabloda etkinleştirebilirsiniz , yani IDENTITY
yeni 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 DELETE
kümeyle, tablodaki tüm satırlar, ancak sildiğiniz satırlar OUTPUT
tam olarak aynı tablonun içindedir - ancak id
sü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_INSERT
tekrar 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, IDENTITY
sütunu yeniden boyutlandırın , böylece bir sonraki kayıt sütundaki id
mevcut 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 id
sayı 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 .. INTO
hedef 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.
id
Bı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 INSERT
ve DELETE
tetikleyicileri 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,
id
sütun olarak IDENTITY
,
IDENTITY_INSERT ON
Tablo için ayarla ,
- Masayı doldurun,
- Ayarla
IDENTITY_INSERT OFF
ve
- Kimliği yeniden düzenleyin.
IDENTITY
?