जिस तरह से मैं आपके प्रश्न को समझ रहा हूं, वह यह है कि आपके पास एक स्तंभ के साथ एक मौजूदा तालिका है जो अब तक मैन्युअल मानों के साथ आबाद है, और अब आप (1) इस स्तंभ को एक IDENTITY
स्तंभ बनाना चाहते हैं , और (2) सुनिश्चित करें कि IDENTITY
प्रारंभ मौजूदा पंक्तियों में सबसे हाल के मूल्य से।
सबसे पहले, कुछ परीक्षण डेटा के साथ खेलने के लिए:
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');
लक्ष्य तालिका के प्राथमिक कुंजी कॉलम को बनाना है id
, एक IDENTITY
कॉलम जो अगले रिकॉर्ड के लिए 21 पर शुरू होगा जो सम्मिलित हो जाता है। इस उदाहरण के लिए, स्तंभ xyz
तालिका के सभी अन्य स्तंभों का प्रतिनिधित्व करता है।
इससे पहले कि आप कुछ भी करें, कृपया इस पोस्ट के नीचे चेतावनी पढ़ें।
सबसे पहले, अगर कुछ गलत हो जाता है:
BEGIN TRANSACTION;
अब, एक अस्थायी कार्य कॉलम जोड़ते हैं, id_temp
और उस कॉलम को मौजूदा id
कॉलम के मानों पर सेट करते हैं:
ALTER TABLE dbo.ident_test ADD id_temp int NULL;
UPDATE dbo.ident_test SET id_temp=id;
अगला, हमें मौजूदा id
कॉलम को ड्रॉप करने की आवश्यकता है (आप मौजूदा कॉलम में सिर्फ "जोड़" नहीं सकते IDENTITY
, आपको कॉलम को एक के रूप में बनाना होगा IDENTITY
)। प्राथमिक कुंजी को भी जाना है, क्योंकि स्तंभ इस पर निर्भर करता है।
ALTER TABLE dbo.ident_test DROP CONSTRAINT PK_ident_test;
ALTER TABLE dbo.ident_test DROP COLUMN id;
... और IDENTITY
प्राथमिक कुंजी के साथ , इस बार फिर से कॉलम जोड़ें :
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);
यहां यह दिलचस्प है। आप IDENTITY_INSERT
तालिका पर सक्षम कर सकते हैं , जिसका अर्थ है कि आप मैन्युअल रूप से एक IDENTITY
स्तंभ के मूल्यों को परिभाषित कर सकते हैं जब आप नई पंक्तियाँ डाल रहे हैं (मौजूदा पंक्तियों को अपडेट नहीं कर रहे हैं, हालांकि)।
SET IDENTITY_INSERT dbo.ident_test ON;
उस सेट के साथ, DELETE
तालिका की सभी पंक्तियाँ, लेकिन आप जिन पंक्तियों को हटा रहे हैं, वे OUTPUT
ठीक उसी तालिका में हैं - लेकिन id
कॉलम के लिए विशिष्ट मानों के साथ (बैकअप कॉलम से)।
DELETE FROM dbo.ident_test
OUTPUT deleted.id_temp AS id, deleted.xyz
INTO dbo.ident_test (id, xyz);
एक बार, किया, IDENTITY_INSERT
फिर से बंद कर दें।
SET IDENTITY_INSERT dbo.ident_test OFF;
हमारे द्वारा जोड़े गए अस्थायी कॉलम को छोड़ें:
ALTER TABLE dbo.ident_test DROP COLUMN id_temp;
और अंत में, IDENTITY
कॉलम id
को फिर से शुरू करें, इसलिए अगले रिकॉर्ड को id
कॉलम में उच्चतम मौजूदा संख्या के बाद फिर से शुरू किया जाएगा :
DECLARE @maxid int;
SELECT @maxid=MAX(id) FROM dbo.ident_test;
DBCC CHECKIDENT ("dbo.ident_test", RESEED, @maxid)
उदाहरण तालिका की जाँच करते हुए, सबसे अधिक id
संख्या 20 है।
SELECT * FROM dbo.ident_test;
एक और पंक्ति जोड़ें और इसकी नई जाँच करें IDENTITY
:
INSERT INTO dbo.ident_test (xyz) VALUES ('New row');
SELECT * FROM dbo.ident_test;
उदाहरण में, नई पंक्ति होगी id=21
। अंत में, यदि आप खुश हैं, तो लेनदेन करें:
COMMIT TRANSACTION;
महत्वपूर्ण
यह एक तुच्छ ऑपरेशन नहीं है, और यह काफी जोखिम भरा है जिसके बारे में आपको जानकारी होनी चाहिए।
इसे समर्पित परीक्षण वातावरण में करें। बैकअप लें। :)
मुझे BEGIN/COMMIT TRANSACTION
इसका उपयोग करना पसंद है क्योंकि यह अन्य प्रक्रियाओं को तालिका के साथ खिलवाड़ करने से रोकता है जबकि आप इसे बदलने के बीच में हैं, और यह आपको कुछ गलत होने पर वापस सब कुछ रोल करने की संभावना देता है। हालाँकि, कोई अन्य प्रक्रिया जो आपके लेन-देन को करने से पहले आपकी तालिका तक पहुँचने की कोशिश करती है, प्रतीक्षा समाप्त हो जाएगी। यदि आपके पास एक बड़ी मेज है और / या आप उत्पादन के माहौल में हैं, तो यह बहुत बुरा हो सकता है।
OUTPUT .. INTO
यदि आपकी लक्ष्य तालिका में विदेशी कुंजी बाधाएँ हैं या ऐसी कई अन्य सुविधाएँ हैं, जिन्हें मैं अपने सिर के ऊपर से याद नहीं रख सकता, तो काम नहीं करेगा। आप इसके बजाय डेटा को एक अस्थायी तालिका में बंद कर सकते हैं, और फिर इसे मूल तालिका में वापस सम्मिलित कर सकते हैं। आप विभाजन स्विचिंग का उपयोग करने में सक्षम हो सकते हैं (भले ही आप विभाजन का उपयोग न करें)।
इन कथनों को एक-एक करके चलाएं, न कि एक बैच के रूप में या एक संग्रहीत प्रक्रिया में।
अन्य चीजों के बारे में सोचने की कोशिश करें, जो उस id
स्तंभ पर निर्भर हो सकती हैं जिसे आप छोड़ रहे हैं और फिर से बना रहे हैं। किसी भी इंडेक्स को छोड़ना होगा और फिर से बनाया जाएगा (जैसे हमने प्राथमिक कुंजी के साथ किया था)। हर सूचकांक और बाधा को स्क्रिप्ट के लिए याद रखें जिसे आपको पहले से बनाए रखना होगा।
किसी भी को अक्षम करें INSERT
और DELETE
तालिका पर ट्रिगर करें ।
यदि तालिका को फिर से बनाना एक विकल्प है:
यदि टेबल को फिर से बनाना आपके लिए एक विकल्प है, तो सब कुछ बहुत सरल है:
- खाली तालिका बनाएँ, साथ
id
एक के रूप में स्तंभ IDENTITY
,
IDENTITY_INSERT ON
तालिका के लिए सेट करें ,
- तालिका पॉप्युलेट करें,
- सेट करें
IDENTITY_INSERT OFF
, और
- पहचान उजागर की।
IDENTITY
?