SQL सर्वर में रिकॉर्ड हटाने के बाद पहचान बीज रीसेट करें


682

मैंने SQL सर्वर डेटाबेस तालिका में रिकॉर्ड सम्मिलित किया है। तालिका में एक प्राथमिक कुंजी निर्धारित की गई थी और ऑटो वृद्धि पहचान बीज "हां" पर सेट है। यह मुख्य रूप से किया जाता है क्योंकि SQL Azure में, प्रत्येक तालिका में एक प्राथमिक कुंजी और पहचान निर्धारित होती है।

लेकिन चूंकि मुझे टेबल से कुछ रिकॉर्ड्स को हटाना है, इसलिए उन टेबल के लिए पहचान पत्र में गड़बड़ी होगी और इंडेक्स कॉलम (जो कि 1 की वृद्धि के साथ ऑटो-जेनरेट होता है) में गड़बड़ी हो जाएगी।

रिकॉर्ड्स को हटाने के बाद मैं पहचान कॉलम को कैसे रीसेट कर सकता हूं ताकि कॉलम में संख्यात्मक क्रम आरोही हो?

पहचान कॉलम का उपयोग डेटाबेस में कहीं भी विदेशी कुंजी के रूप में नहीं किया जाता है।


4
"SQL अज़ुरे में" - "प्रत्येक तालिका में एक प्राथमिक कुंजी होनी चाहिए" - सत्य - "और पहचान परिभाषित" - असत्य। पहचान और प्राथमिक कुंजी रूढ़िवादी अवधारणाएं हैं। एक पहचान कॉलम में तालिका का PK नहीं होना चाहिए। एक प्राथमिक कुंजी के लिए एक पहचान कॉलम नहीं होना चाहिए।
डेमियन___बेलिवर

ठीक। मेरी अवधारणा गलत हो सकती है। लेकिन अब मैंने पीके और आइडेंटिटी सीड के साथ टेबल संरचना को परिभाषित किया है। अगर मुझे कुछ पंक्तियों को हटाना है, तो मैं एक सही संख्या में आरोही क्रम में आईडेंटिटी सीड को कैसे रीसेट कर सकता हूं
xorpower

29
मैं हमेशा यह तर्क दूंगा कि यदि आप किसी पहचान कॉलम में उत्पन्न वास्तविक संख्यात्मक मूल्यों की परवाह करते हैं, तो आप उनका दुरुपयोग कर रहे हैं। आपको एक पहचान स्तंभ के बारे में ध्यान रखना चाहिए कि यह स्वचालित रूप से अनन्य मान (या!) उत्पन्न करता है और आप इन मानों को एक संख्यात्मक कॉलम में संग्रहीत कर सकते हैं (यह बिट इन मानों को रखने के लिए कॉलम घोषित करने के लिए केवल प्रासंगिक है)। आप उन्हें किसी को भी नहीं दिखा रहे हैं, इसलिए यह मायने नहीं रखना चाहिए कि वे क्या मूल्य लेते हैं।
डेमियन___बेलिवर

आप अन्य उल्लेख के रूप में dbcc जाँच पहचान का उपयोग कर सकते हैं, लेकिन कृपया ध्यान दें कि sql db v12 के लिए प्राथमिक कुंजी अनिवार्य नहीं है
Satya_MSFT

जवाबों:


1099

DBCC CHECKIDENTप्रबंधन कमांड पहचान काउंटर रीसेट करने के लिए प्रयोग किया जाता है। कमांड सिंटैक्स है:

DBCC CHECKIDENT (table_name [, { NORESEED | { RESEED [, new_reseed_value ]}}])
[ WITH NO_INFOMSGS ]

उदाहरण:

DBCC CHECKIDENT ('[TestTable]', RESEED, 0);
GO

यह Azure SQL डेटाबेस के पिछले संस्करणों में समर्थित नहीं था, लेकिन अब समर्थित है।


कृपया ध्यान दें कि new_reseed_valueतर्क प्रलेखन के अनुसार SQL सर्वर संस्करणों में भिन्न है :

यदि पंक्तियाँ तालिका में मौजूद हैं, तो अगली पंक्ति new_reseed_value मान के साथ डाली गई है । SQL Server 2008 R2 और इससे पहले के संस्करण में, अगली पंक्ति सम्मिलित की गई new_reseed_value + वर्तमान वेतन वृद्धि का उपयोग करती है

हालाँकि, मुझे यह जानकारी भ्रामक लगती है (सिर्फ सादा गलत वास्तव में) क्योंकि देखा गया व्यवहार बताता है कि कम से कम SQL Server 2012 अभी भी new_reseed_value + वर्तमान वेतन वृद्धि तर्क का उपयोग करता है। Microsoft Example Cने उसी पृष्ठ पर अपने स्वयं के साथ विरोधाभास किया :

C. वर्तमान पहचान मूल्य को एक नए मूल्य के लिए मजबूर करना

निम्न उदाहरण AddressType तालिका में वर्तमान पहचान मान को AddressType तालिका में 10. के मान पर बाध्य करता है क्योंकि तालिका में मौजूदा पंक्तियाँ हैं, अगली पंक्ति सम्मिलित मान के रूप में 11 का उपयोग करेगी, अर्थात, नया वर्तमान वेतन वृद्धि मान स्तंभ मान प्लस 1।

USE AdventureWorks2012;  
GO  
DBCC CHECKIDENT ('Person.AddressType', RESEED, 10);  
GO

फिर भी, यह सभी नए SQL सर्वर संस्करणों पर विभिन्न व्यवहार के लिए एक विकल्प छोड़ देता है। मैं यह सुनिश्चित करने का एकमात्र तरीका हूं, जब तक कि Microsoft अपने स्वयं के प्रलेखन में चीजों को साफ न कर दे, उपयोग से पहले वास्तविक परीक्षण करना है।


23
सिंटेक्स होगा ... DBCC CHECKIDENT ('[TestTable]', RESEED, 0) GO
Biki

2
ऐसा प्रतीत होता है कि DBCC CHECKIDENTआगामी रिलीज़ (V12 / Sterling) के रूप में समर्थित है: azure.microsoft.com/en-us/documentation/articles/… हालांकि, इस विशेष स्थिति के लिए, मैं अभी भी TRUNCATE टेबल की सिफारिश करूंगा :)
सुलैमान रुतज़े

1
यह मेरे लिए तब तक काम नहीं आया जब तक "गो" दूसरी लाइन में नहीं था।
म्रवा

1
एक ही पंक्ति में GO कीवर्ड के कारण सिंटैक्स को ध्वजांकित किया जा रहा है, मुझे नहीं पता कि क्यों। क्या आप इसे एक पंक्ति में ले जा सकते हैं। मैंने इस लाइन को 50 बार कॉपी और पेस्ट किया और अब मुझे इसे ठीक करना है।
अविकसित

4
मेरे लिए पूरी तरह से काम किया। यह इंगित करने के लायक है कि जब किसी तालिका को फिर से बीजारोपण किया जाता है, यदि आप फिर से शुरू करना चाहते हैं ताकि आपका पहला रिकॉर्ड ID 1 हो, तो reseed कमांड को 0 पर फिर से भेजना होगा, ताकि अगला रिकॉर्ड ID 1 हो
माइक अपजॉन

215
DBCC CHECKIDENT ('TestTable', RESEED, 0)
GO

जहां 0 identityस्टार्ट वैल्यू है


15
यदि तालिका खाली है, जैसे कि यदि आपने अभी फोन किया है TRUNCATE, तो नए बीज का मान अगले उपयोग का मान होना चाहिए (अर्थात 1 नहीं 0)। यदि तालिका खाली नहीं है तो इसका उपयोग किया जाएगा new_reseed_value + 1MSDN
kjbartel

2
@kjbartel, अनिल, और अन्य: यह सिर्फ "टेबल खाली है तो" जितना सरल नहीं है। प्रलेखन के लिए मामला गायब था, जब तालिका खाली है DELETE, नहीं TRUNCATE, इस मामले में यह भी है new_reseed+value + 1। मैंने इसके बारे में एक पोस्ट लिखी, जिसमें कुछ परीक्षणों के माध्यम से वास्तविक व्यवहार को दिखाया गया, और वास्तविक डॉक्टर को अपडेट किया (अब जो हम इसके कारण GitHub पर हैं): कैसे DBCC CHECKIDENT वास्तव में काम करता है जब आइडेंटिटी सीड (RESEED) को रीसेट किया जाता है?
सोलोमन रटज़की

87

यह ध्यान दिया जाना चाहिए कि यदि सभी डेटा तालिका से DELETE(अर्थात कोई WHEREखंड) के माध्यम से हटाया जा रहा है , तो जब तक क) अनुमतियाँ इसके लिए अनुमति देती हैं, और b) तालिका को संदर्भित करने वाला कोई FK नहीं हैं (जो प्रतीत होता है) यहाँ मामला), का उपयोग TRUNCATE TABLEकरना पसंद किया जाएगा क्योंकि यह अधिक कुशल है DELETE औरIDENTITY एक ही समय में बीज को रीसेट करता है । निम्नलिखित विवरण TRUNCATE टेबल के लिए MSDN पृष्ठ से लिए गए हैं :

DELETE कथन की तुलना में TRUNCATE TABLE के निम्नलिखित लाभ हैं:

  • कम लेन-देन लॉग स्पेस का उपयोग किया जाता है।

    DELETE कथन पंक्तियों को एक बार में हटाता है और प्रत्येक हटाए गए पंक्ति के लिए लेनदेन लॉग में एक प्रविष्टि दर्ज करता है। TRUNCATE टेबल तालिका डेटा को संग्रहीत करने के लिए उपयोग किए गए डेटा पृष्ठों को हटाकर डेटा को हटाता है और लेनदेन लॉग में केवल पृष्ठ डीलक्लोशंस रिकॉर्ड करता है।

  • आमतौर पर कम ताले का उपयोग किया जाता है।

    जब DELETE स्टेटमेंट को एक पंक्ति लॉक का उपयोग करके निष्पादित किया जाता है, तो तालिका में प्रत्येक पंक्ति को हटाने के लिए लॉक किया जाता है। TRUNCATE टेबल हमेशा टेबल को लॉक करता है (स्कीमा (SCH-M) लॉक सहित) और पेज लेकिन प्रत्येक पंक्ति नहीं।

  • अपवाद के बिना, तालिका में शून्य पृष्ठ छोड़ दिए जाते हैं।

    DELETE कथन निष्पादित होने के बाद, तालिका में अभी भी खाली पृष्ठ हो सकते हैं। उदाहरण के लिए, एक हीप में खाली पृष्ठों को कम से कम एक अनन्य (LCK_M_X) टेबल लॉक के बिना नहीं हटाया जा सकता है। यदि डिलीट ऑपरेशन टेबल लॉक का उपयोग नहीं करता है, तो टेबल (हीप) में कई खाली पृष्ठ होंगे। अनुक्रमित के लिए, डिलीट ऑपरेशन खाली पन्नों को पीछे छोड़ सकता है, हालांकि इन पृष्ठों को पृष्ठभूमि सफाई प्रक्रिया द्वारा जल्दी से निपटाया जाएगा।

यदि तालिका में एक पहचान स्तंभ है, तो उस स्तंभ के लिए काउंटर स्तंभ के लिए परिभाषित बीज मान पर रीसेट हो जाता है। यदि कोई बीज परिभाषित नहीं किया गया था, तो डिफ़ॉल्ट मान 1 का उपयोग किया जाता है। पहचान काउंटर को बनाए रखने के लिए, इसके बजाय DELETE का उपयोग करें।

तो निम्नलिखित है:

DELETE FROM [MyTable];
DBCC CHECKIDENT ('[MyTable]', RESEED, 0);

बस बन जाता है:

TRUNCATE TABLE [MyTable];

कृपया TRUNCATE TABLEप्रतिबंधों पर अतिरिक्त जानकारी के लिए प्रलेखन (ऊपर जुड़ा हुआ) देखें, आदि।


8
जबकि सही परिस्थितियों में अधिक कुशल, यह हमेशा एक विकल्प नहीं होता है। ट्रंकट उस मेज पर निष्पादित नहीं होगा, जिसके पास एफके परिभाषित है। जब कोई आश्रित रिकॉर्ड नहीं होता है, तब भी अगर बाधा मौजूद है, तो ट्रंकट विफल हो जाएगा। इसके अलावा ट्रंकट को ALTER अनुमतियों की आवश्यकता होती है जहां डिलीट केवल DELETE की आवश्यकता है।
Rozwel

3
@Rozwel सच है, लेकिन मैंने पहले ही अपना जवाब योग्य बताते हुए कहा कि उचित अनुमतियों की आवश्यकता है। साथ ही, यह प्रश्न विशेष रूप से बताता है कि एफके नहीं हैं। हालाँकि, स्पष्टता के लिए, मैंने "नो एफके" प्रतिबंध को निर्दिष्ट करने के लिए अद्यतन किया। यह बात बताने के लिए धन्यवाद।
सोलोमन रटज़की 15

1
केवल वक्रोक्ति यह है कि कोई भी FK ट्रंकट को अवरुद्ध करेगा। यह संभव है (हालांकि असामान्य) एक अद्वितीय बाधा के खिलाफ एफके होना जो कि पीके या पहचान कॉलम का हिस्सा नहीं है।
रोज़वेल

1
@Rozwel फिर से सच है, लेकिन यह इस सवाल से मुनासिब लगता है कि इसमें कोई अनोखी अड़चन नहीं है कि पीके केवल ओपी की समझ (सही है या नहीं) की वजह से मौजूद है कि यह Azure SQL डेटाबेस द्वारा आवश्यक है। भले ही, मैं अस्पष्टता को कम करने के लिए सभी हूं इसलिए मैंने फिर से अपडेट किया है। धन्यवाद।
सोलोमन रटज़की

यह सब एक टेबल पर एक विदेशी कुंजी होने के लिए असामान्य नहीं है, और किसी भी विदेशी कुंजी की उपस्थिति TRUNCATE टेबल को प्रतिबंधित करती है। मैंने आज ही सबसे पहले यह कठिन तरीका खोजा था जब मैंने एक टेबल पर TRUNCATE TABLE को चलाने का प्रयास किया था जिसमें एक विदेशी कुंजी होती है जिसे टेबल में दो अन्य कॉलमों के खिलाफ लागू किया जाता है और विदेशी तालिका में एक अद्वितीय सूचकांक होता है।
डेविड ए। ग्रे

83

हालाँकि ज्यादातर जवाब 0 के लिए सुरक्षित होने का सुझाव दे रहे हैं, लेकिन कई बार हमें केवल अगली ईद पर उपलब्ध होने की आवश्यकता होती है

declare @max int
select @max=max([Id])from [TestTable]
if @max IS NULL   //check when max is returned as null
  SET @max = 0
DBCC CHECKIDENT ('[TestTable]', RESEED,@max)

यह तालिका की जांच करेगा और अगली आईडी पर रीसेट करेगा।


2
यह एकमात्र उत्तर है जो 100% समय काम करता है
उल्टा इंजीनियर

3
थोड़ा छोटा:declare @max int select @max=ISNULL(max([Id]),0) from [TestTable]; DBCC CHECKIDENT ('[TestTable]', RESEED, @max );
गिलर्मो प्रांडी

61

मैंने @anil shahsजवाब देने की कोशिश की और यह पहचान को रीसेट करता है। लेकिन जब एक नई पंक्ति डाली गई तो उसे मिल गया identity = 2। इसलिए इसके बजाय मैंने सिंटैक्स को इसमें बदल दिया:

DELETE FROM [TestTable]

DBCC CHECKIDENT ('[TestTable]', RESEED, 0)
GO

फिर पहली पंक्ति को पहचान = 1 मिलेगी।



16

यद्यपि अधिकांश जवाब सुझाव दे रहे हैं RESEEDकरने के लिए 0, और जबकि कुछ के लिए एक दोष के रूप में देखते TRUNCATEDटेबल, माइक्रोसॉफ्ट कि एक समाधान है शामिल नहींID

DBCC CHECKIDENT ('[TestTable]', RESEED)

यह तालिका की जांच करेगा और अगले पर रीसेट करेगा ID। यह MS SQL 2005 से वर्तमान तक उपलब्ध है।

https://msdn.microsoft.com/en-us/library/ms176057.aspx


1
दुर्भाग्य से यह सच नहीं है। बस MS SQL 2014 सर्वर के लिए जाँच की है।
एलेरो

1
दरअसल, यह SQL 2014 के लिए सच है। मैंने अभी इसका परीक्षण किया है और इसने मेरे लिए काम किया है।
डैनियल डायसन

2
यह SQL 2012 पर मेरे लिए असंगत रूप से काम करता है। कभी-कभी यह अगले उपलब्ध का उपयोग करता है जैसा कि मैंने उम्मीद की थी, कभी-कभी यह टेबल से एक पुराने मूल्य पर अटक जाता है। बीज अलवासी कार्यों को निर्दिष्ट करना।
दान फील्ड

SQL 2016 पर मेरे लिए काम नहीं करता है - यह सिर्फ पहचान के बीज को छोड़ देता है। हो सकता है कि उसने एक बार मेरे लिए सही तरीके से काम किया हो, लेकिन यह मेरी उंगली की परेशानी भी हो सकती है। फिर से काम करने के लिए नहीं मिल सकता है
उलट इंजीनियर

संदेश सफलता को इंगित करता है Checking identity information: current identity value '[incorrect seed]', current column value '[correct seed]'., लेकिन नए आवेषण पर यह अभी भी गलत बीज का उपयोग कर रहा है।
डेन्ज़िलो

7

2 कमांड जारी करने का काम कर सकता है

DBCC CHECKIDENT ('[TestTable]', RESEED,0)
DBCC CHECKIDENT ('[TestTable]', RESEED)

पहले पहचान को शून्य पर रीसेट करें, और अगला इसे अगले उपलब्ध मूल्य पर सेट करेगा - जैकोब


2
DBCC CHECKIDENT ('[TestTable]', RESEED) अगले उपलब्ध मूल्य के अनुरूप नहीं है
अटल किशोर

यह RedGate डेटा तुलना द्वारा उपयोग की जाने वाली विधि है जब विकल्प " रीज़ेड आइडेंट कॉलम" चालू होता है। मैंने इसे बड़े पैमाने पर परीक्षण किया है (मेरा मतलब SQL कोड में है, RedGate टूल में नहीं), और यह मज़बूती से काम करता है। (मेरा उनके परीक्षण संस्करणों के एक सामयिक उपयोगकर्ता होने के अलावा RedGate से कोई संबंध नहीं है)
उलटा इंजीनियर

6

@jacob

DBCC CHECKIDENT ('[TestTable]', RESEED,0)
DBCC CHECKIDENT ('[TestTable]', RESEED)

मेरे लिए काम किया, मुझे बस पहले सभी प्रविष्टियों को तालिका से साफ़ करना था, फिर हटाने के बाद ट्रिगर बिंदु में ऊपर जोड़ा। अब जब भी मैं डिलीट करता हूं तो वहां से एंट्री ली जाती है।


हटाने के बाद DBCC CHECKIDENT केवल कार्यात्मक है। आप ट्रंकट का उपयोग भी कर सकते हैं। हालाँकि, यदि आपको बाकी डेटा की आवश्यकता है, तो इसका उपयोग न करें। ट्रंकैट डिलीट किए गए रिकॉर्ड की रिकॉर्ड गणना नहीं देता है।
user763539

6

Truncate तालिका को पसंद किया जाता है क्योंकि यह रिकॉर्ड्स को साफ़ करता है, काउंटर को रीसेट करता है और डिस्क स्थान को पुनः प्राप्त करता है।

Deleteऔर CheckIdentकेवल उसी जगह का उपयोग किया जाना चाहिए जहां विदेशी चाबियां आपको छंटनी से रोकती हैं।


5

नई आईडी के साथ पहचान कॉलम रीसेट करें ...

DECLARE @MAX INT
SELECT @MAX=ISNULL(MAX(Id),0) FROM [TestTable]

DBCC CHECKIDENT ('[TestTable]', RESEED,@MAX)

4

यह एक सामान्य प्रश्न है और इसका उत्तर हमेशा एक ही होता है: ऐसा न करें। पहचान मूल्यों को मनमाना माना जाना चाहिए और, जैसे कि, कोई "सही" आदेश नहीं है।


15
यह उत्पादन के माहौल के लिए सही है, लेकिन विकसित होने के दौरान मुझे यह याद रखना पसंद है कि कुछ संस्थाओं के पास एक निश्चित आईडी होती है, जो एक बोने की स्क्रिप्ट से आबाद होती है। यह विकास में रहते हुए डेटाबेस के माध्यम से नेविगेट करना बहुत आसान बनाता है।
फ्रेंकोइस बोथा

7
इस तरह के उत्तर पूरी तरह से सैद्धांतिक हैं और शायद ही कभी वे वास्तविक दुनिया की जरूरतों का अनुपालन करते हैं। कैसे अपनी हठधर्मिता के साथ लोगों का ब्रेनवॉश करने के बजाय, आप ओपी सवाल का जवाब देते हैं ...
सर्ज सागर

1
मजेदार कहानी है भाई। मेरा तर्क यह है: यदि आप किसी स्तंभ के लिए मान निर्दिष्ट करना चाहते हैं, तो उस स्तंभ पर कोई गुण न चुनें जो ऐसा करना कठिन बनाता है। कोड गंध यह है: यदि हर बार जब आप किसी तालिका में रिकॉर्ड डालते हैं तो आप पहचान कॉलम के लिए एक मान निर्दिष्ट करते हैं, तो आपके पास पहचान कॉलम नहीं होता है। पहचान का पूरा बिंदु सर्वर को आपके लिए एक मूल्य बनाना है। इसलिए यदि आप उस समय को ओवरराइड करते हैं, तो आपने गैर-शून्य लागत के लिए कुछ भी नहीं प्राप्त किया है। इसके अलावा, विज्ञापन होमिनीम तर्क पर अच्छा काम करते हैं।
बेन थुल

5
मैं निश्चित रूप से आपके विवाद से सहमत हूं। अंकित मूल्य को देखते हुए, ओपी निश्चित रूप से इसे गलत कर रहा है, लेकिन शायद पोस्ट में एक गहरी आवश्यकता नहीं बताई गई है जिसे ओपी ने अपने प्रश्न का उत्तर देने के लिए प्रासंगिक नहीं माना था। इसलिए प्रश्न का उत्तर दें, और उत्तर के भाग के रूप में "क्या करें और क्या न करें" सलाह दें। वैसे, मैंने आपके चरित्र पर कभी हमला नहीं किया ... विज्ञापन होमिनम का अर्थ है कि मैंने आपको बेवकूफ या कुछ और कहा ...
सेरज सगन

1
हालांकि ज्यादातर मामलों में निश्चित रूप से सच है, ऐसी परिस्थितियां हैं जिनमें यह एक तालिका को फिर से बीज करने के लिए वैध है। उदाहरण के लिए, मैं एक ग्रीनफील्ड परियोजना पर काम कर रहा हूं जो कि पूर्ववर्ती में मौजूदा पंक्तियों के लिए एक निश्चित बिंदु से शुरू होनी चाहिए जो इसे प्रतिस्थापित कर रही है। विकास के दौरान रीसेडिंग एक वैध उपयोग का मामला है, IMO।
डेविड ए। ग्रे

3

पहचान कॉलम को रीसेट करने के लिए इस स्क्रिप्ट को चलाएँ। आपको दो बदलाव करने होंगे। जो भी टेबल आपको अपडेट करना है, उसे टेबलएक्सवायजेड से बदलें। इसके अलावा, पहचान स्तंभ का नाम अस्थायी तालिका से हटा दिया गया है। यह 35,000 पंक्तियों और 3 स्तंभों वाली एक मेज पर तात्कालिक था। जाहिर है, तालिका का बैकअप लें और पहले इसे एक परीक्षण वातावरण में आज़माएं।


select * 
into #temp
From tableXYZ

set identity_insert tableXYZ ON

truncate table tableXYZ

alter table #temp drop column (nameOfIdentityColumn)

set identity_insert tableXYZ OFF

insert into tableXYZ
select * from #temp

3
यह पूरी तरह से सही नहीं है: सेट IDENTITY_INSERT गलत जगह पर है। यह TRUNCATE के आसपास नहीं जाता है, यह INSERT INTO (इसलिए पहचान_ INSERT ) के आसपास जाता है । इसके अलावा, इसका उपयोग केवल तब किया जाना चाहिए जब डेटा को रखा जाना चाहिए, अन्यथा यह केवल एकल ट्रेंक्यू स्टेटमेंट को चलाने की तुलना में बहुत अक्षम है।
सोलोमन रटज़की

1
DBCC CHECKIDENT (<TableName>, reseed, 0)

यह वर्तमान पहचान मान को 0 पर सेट करेगा।

अगला मान सम्मिलित करने पर, पहचान मान 1 हो जाता है।


1

इस संग्रहीत कार्यविधि का उपयोग करें:

IF (object_id('[dbo].[pResetIdentityField]') IS NULL)
  BEGIN
    EXEC('CREATE PROCEDURE [dbo].[pResetIdentityField] AS SELECT 1 FROM DUMMY');
  END
GO

SET  ANSI_NULLS ON
GO
SET  QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[pResetIdentityField]
  @pSchemaName NVARCHAR(1000)
, @pTableName NVARCHAR(1000) AS
DECLARE @max   INT;
DECLARE @fullTableName   NVARCHAR(2000) = @pSchemaName + '.' + @pTableName;

DECLARE @identityColumn   NVARCHAR(1000);

SELECT @identityColumn = c.[name]
FROM sys.tables t
     INNER JOIN sys.schemas s ON t.[schema_id] = s.[schema_id]
     INNER JOIN sys.columns c ON c.[object_id] = t.[object_id]
WHERE     c.is_identity = 1
      AND t.name = @pTableName
      AND s.[name] = @pSchemaName

IF @identityColumn IS NULL
  BEGIN
    RAISERROR(
      'One of the following is true: 1. the table you specified doesn''t have an identity field, 2. you specified an invalid schema, 3. you specified an invalid table'
    , 16
    , 1);
    RETURN;
  END;

DECLARE @sqlString   NVARCHAR(MAX) = N'SELECT @maxOut = max(' + @identityColumn + ') FROM ' + @fullTableName;

EXECUTE sp_executesql @stmt = @sqlString, @params = N'@maxOut int OUTPUT', @maxOut = @max OUTPUT

IF @max IS NULL
  SET @max = 0

print(@max)

DBCC CHECKIDENT (@fullTableName, RESEED, @max)
go

--exec pResetIdentityField 'dbo', 'Table'

बस मेरा जवाब फिर से आना। मुझे sql सर्वर 2008 r2 में एक अजीब व्यवहार के बारे में पता चला, जिसके बारे में आपको जानकारी होनी चाहिए।

drop table test01

create table test01 (Id int identity(1,1), descr nvarchar(10))

execute pResetIdentityField 'dbo', 'test01'

insert into test01 (descr) values('Item 1')

select * from test01

delete from test01

execute pResetIdentityField 'dbo', 'test01'

insert into test01 (descr) values('Item 1')

select * from test01

पहला चयन करता है 0, Item 1

दूसरा पैदा करता है 1, Item 1। यदि आप तालिका सही करने के बाद रीसेट रीसेट करते हैं, तो अगला मान 0. है। ईमानदारी से, मुझे आश्चर्य नहीं है कि Microsoft को यह सामान सही नहीं मिल सकता है। मैंने इसकी खोज की क्योंकि मेरे पास एक स्क्रिप्ट फ़ाइल है जो संदर्भ तालिकाओं को पॉप्युलेट करती है जिसे मैं कभी-कभी टेबल बनाने के बाद चलाता हूं और कभी-कभी जब टेबल पहले से ही बनाई जाती हैं।


1

मैं ऐसा करने के लिए निम्न स्क्रिप्ट का उपयोग करता हूं। केवल एक परिदृश्य है जिसमें यह एक "त्रुटि" उत्पन्न करेगा, जो कि यदि आपने तालिका से सभी पंक्तियों को हटा दिया है, और IDENT_CURRENTवर्तमान में 1 पर सेट है, तो शुरू करने के लिए तालिका में केवल एक पंक्ति थी।

DECLARE @maxID int = (SELECT MAX(ID) FROM dbo.Tbl)
;

IF @maxID IS NULL
    IF (SELECT IDENT_CURRENT('dbo.Tbl')) > 1
        DBCC CHECKIDENT ('dbo.Tbl', RESEED, 0)
    ELSE
        DBCC CHECKIDENT ('dbo.Tbl', RESEED, 1)
    ;
ELSE
    DBCC CHECKIDENT ('dbo.Tbl', RESEED, @maxID)
;

0

एक पूर्ण DELETE पंक्तियों के लिए और पहचान की संख्या को रीसेट करने के लिए, मैं इसका उपयोग करता हूं (SQL Server 2008 R2)

USE mydb

-- ##################################################################################################################
-- DANGEROUS!!!! USE WITH CARE
-- ##################################################################################################################

DECLARE
  db_cursor CURSOR FOR
    SELECT TABLE_NAME
      FROM INFORMATION_SCHEMA.TABLES
     WHERE TABLE_TYPE = 'BASE TABLE'
       AND TABLE_CATALOG = 'mydb'

DECLARE @tblname VARCHAR(50)
SET @tblname = ''

OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @tblname

WHILE @@FETCH_STATUS = 0
BEGIN
  IF CHARINDEX('mycommonwordforalltablesIwanttodothisto', @tblname) > 0
    BEGIN
      EXEC('DELETE FROM ' + @tblname)
      DBCC CHECKIDENT (@tblname, RESEED, 0)
    END

  FETCH NEXT FROM db_cursor INTO @tblname
END

CLOSE db_cursor
DEALLOCATE db_cursor
GO

0

जब तक आप टेबल को पूरी तरह से साफ नहीं कर रहे हैं, तब तक रीसेडिंग करना बहुत व्यावहारिक नहीं है।

अन्य बुद्धिमान एंथनी रेमंड द्वारा दिया गया उत्तर एकदम सही है। पहले पहचान कॉलम की अधिकतम प्राप्त करें, फिर इसे अधिकतम के साथ बीज दें।


0

मैं विकास के दौरान बड़ी संख्या में तालिकाओं के लिए यह करने की कोशिश कर रहा हूं, और यह एक आकर्षण के रूप में काम करता है।

DBCC CHECKIDENT('www.newsType', RESEED, 1);
DBCC CHECKIDENT('www.newsType', RESEED);

तो, आप पहले इसे 1 पर सेट करने के लिए मजबूर करते हैं, फिर आप इसे तालिका में मौजूद पंक्तियों के उच्चतम सूचकांक पर सेट करते हैं। त्वरित और आसान idex के बाकी।


-2

TRUNCATE का उपयोग करना हमेशा बेहतर होता है जब सभी रिकॉर्ड को हटाने के बजाय संभव हो, क्योंकि यह लॉग स्पेस का भी उपयोग नहीं करता है।

मामले में हमें हटाने की आवश्यकता है और बीज को रीसेट करने की आवश्यकता है, हमेशा याद रखें कि यदि टेबल कभी आबाद नहीं हुई थी और आपने इस्तेमाल किया था DBCC CHECKIDENT('tablenem',RESEED,0) तो पहले रिकॉर्ड को पहचान मिलेगी = 0 जैसा कि एमएसडीएन प्रलेखन पर कहा गया है

आपके मामले में केवल सूचकांक को फिर से बनाना और पहचान की श्रृंखला को खोने के बारे में चिंता न करें क्योंकि यह एक सामान्य परिदृश्य है।


3
मुझे लगता है कि यह विचार केवल कुछ रिकॉर्ड को हटाने के लिए है ।
द्रुमबेग

6
यह सिर्फ स्पष्ट गलत है - यह <i> ALWAYS </ i> ट्रंकट का उपयोग करने के लिए बेहतर नहीं है और वास्तव में, केवल कुछ, बहुत सीमित और विशिष्ट परिदृश्यों में बेहतर है। स्वर्ग में किसी को आपकी सलाह का पालन करना था और फिर रोलबैक करने की आवश्यकता थी।
थ्रोनक

1
@ थ्रोंक आप ऐसा क्यों लगा रहे हैं जो उम्मीद के TRUNCATEमुताबिक ROLLBACKबर्ताव करने से रोकेगा ? रोलबैक अभी भी रोल-बैक। यहां तक कि अगर डीबी के लिए निर्धारित है BULK_LOGGED
सोलोमन रटज़स्की

2
TRUNCATE DDL ऑपरेशन है और यह लॉग फ़ाइल में लॉग नहीं है। जब तक यह लेनदेन का हिस्सा नहीं है (प्रश्न में या इस उत्तर में कहीं भी उल्लेख नहीं किया गया है)। जब भी कोई कहता है कि कुछ सच है, तो यह एक बहुत ही सुरक्षित शर्त है कि वे गलत हैं।
थ्रॉन्क

यह एकमात्र उत्तर है कि नोटों में इस बात पर निर्भर है कि अनुक्रम व्यवहार में कोई अंतर है या नहीं, यह अनुक्रम पहले इस्तेमाल किया गया था या नहीं। एक से अधिक खाली में एक ही मान का पुनर्निमाण तालिकाओं , जहां कुछ तालिकाओं को पहले आबाद किया गया था, प्रत्येक तालिका में डाले गए पहले रिकॉर्ड के लिए अलग-अलग प्रारंभिक मान होंगे।
सिमोन कोलमैन

-4

पहला: आइडेंटिटी स्पेसिफिकेशन जस्ट: "नहीं" >> डेटाबेस एक्सेक्यूट प्रोजेक्ट को सेव करें

उसके बाद: आइडेंटिटी स्पेसिफिकेशन जस्ट: "YES" >> डेटाबेस एक्सेक्यूट प्रोजेक्ट को सेव करें

आपका डेटाबेस आईडी, पीके 1 >> से शुरू होता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.