मौजूदा कॉलम में एक पहचान जोड़ना


445

मुझे तालिका की प्राथमिक कुंजी को पहचान कॉलम में बदलने की आवश्यकता है, और तालिका में पहले से ही कई पंक्तियाँ हैं।

मुझे यह सुनिश्चित करने के लिए एक स्क्रिप्ट मिली है कि आईडी को साफ करने के लिए कि वे अनुक्रमिक 1 पर शुरू कर रहे हैं, मेरे परीक्षण डेटाबेस पर ठीक काम करता है।

पहचान संपत्ति के लिए कॉलम को बदलने के लिए SQL कमांड क्या है?

जवाबों:


482

आप पहचान के लिए मौजूदा कॉलम को बदल नहीं सकते।

आपके पास 2 विकल्प हैं,

  1. पहचान के साथ एक नई तालिका बनाएं और मौजूदा तालिका को छोड़ दें

  2. पहचान के साथ एक नया कॉलम बनाएं और मौजूदा कॉलम को छोड़ दें

दृष्टिकोण 1. ( नई तालिका ) यहां आप नए बनाए गए पहचान कॉलम पर मौजूदा डेटा मानों को बनाए रख सकते हैं।

CREATE TABLE dbo.Tmp_Names
    (
      Id int NOT NULL
             IDENTITY(1, 1),
      Name varchar(50) NULL
    )
ON  [PRIMARY]
go

SET IDENTITY_INSERT dbo.Tmp_Names ON
go

IF EXISTS ( SELECT  *
            FROM    dbo.Names ) 
    INSERT  INTO dbo.Tmp_Names ( Id, Name )
            SELECT  Id,
                    Name
            FROM    dbo.Names TABLOCKX
go

SET IDENTITY_INSERT dbo.Tmp_Names OFF
go

DROP TABLE dbo.Names
go

Exec sp_rename 'Tmp_Names', 'Names'

दृष्टिकोण 2 ( नया कॉलम ) आप नए बनाए गए पहचान कॉलम पर मौजूदा डेटा मानों को बनाए नहीं रख सकते, पहचान कॉलम नंबर के अनुक्रम को रखेगा।

Alter Table Names
Add Id_new Int Identity(1, 1)
Go

Alter Table Names Drop Column ID
Go

Exec sp_rename 'Names.Id_new', 'ID', 'Column'

अधिक विवरण के लिए निम्नलिखित Microsoft SQL सर्वर फोरम पोस्ट देखें:

कॉलम को पहचान में कैसे बदला जाए (1,1)


49
यदि टेबल डेटा छोटा है, तो यह विकल्प कार्य करता है। यदि तालिका बड़ी है, तो एक और विकल्प है जिसे मैं पसंद करता हूं: ALTER TABLE का उपयोग करें ... तालिका स्कीमा को एक अन्य संस्करण के साथ एक पहचान कॉलम के साथ बदलने के लिए स्विच करें लेकिन अन्यथा समान स्कीमा। ALTER TABLE .... SWITCH दृष्टिकोण का लाभ यह है कि यह जल्दी से पूरा होता है (एक अरब-पंक्ति तालिका के लिए 5 सेकंड के तहत) क्योंकि किसी भी तालिका डेटा को कॉपी या बदलने की आवश्यकता नहीं है। हालांकि कैविटीज़ और सीमाएँ हैं। विवरण के लिए नीचे मेरा उत्तर देखें।
जस्टिन ग्रांट

7
@ जस्टिन ग्राट: एक बहुत ही दिलचस्प विकल्प और एक जिसे मैंने नहीं माना था! इसका कारण यह है क्योंकि IDENTITY एक स्तंभ गुण है और डेटा प्रकार नहीं है, इसलिए SWITCH विधि दो तालिकाओं (पुराने और नए) के बीच स्कीमा को IDENTITY अंतर के पहचान योग्य होने के बावजूद मान्य करता है। साझा करने के लिए धन्यवाद!
जॉन सैंसोम

यदि आपके पास अधिक डेटा नहीं है, तो "टेबल बनाकर" एसएसएमएस से एक स्क्रिप्ट तैयार करके प्राप्त किया जा सकता है। तालिका> स्क्रिप्प तालिका को> क्रिएट टेबल टू> (नया क्वेरी संपादक?) के रूप में राइट क्लिक करें। फिर इसे छोड़ दें, और उस स्क्रिप्ट के अंदर आप IDENTITY(1, 1)प्राथमिक कुंजी कॉलम के साथ भाग जोड़ सकते हैं
goamn

इसे लागू करने के लिए SSMS का उपयोग भी किया जा सकता है। टूल्स> ऑप्शन्स> डिज़ाइनर्स> अन-चेक "अन्डर सेविंग चेंजेजस ठाट टेबल री-क्रिएशन" की आवश्यकता है। BTW यह काफी बड़ी तालिकाओं के लिए अनुशंसित नहीं है।
जफर

PostgreSQL में आप कमांड के साथ मौजूदा पूर्णांक कॉलम में पहचान जोड़ सकते हैं: परिवर्तन तालिका {table_name} परिवर्तन स्तंभ {column_name} हमेशा उत्पन्न पहचान ({संख्या} के साथ पुनरारंभ) के रूप में जोड़ें;
एंड्रयू मैके

209

SQL 2005 और इसके बाद के संस्करण में, तालिका के डेटा पृष्ठों को बदले बिना इस समस्या को हल करने की एक चाल है। यह बड़ी तालिकाओं के लिए महत्वपूर्ण है जहां हर डेटा पृष्ठ को छूने में मिनट या घंटे लग सकते हैं। चाल भी काम करती है भले ही पहचान स्तंभ एक प्राथमिक कुंजी है, एक संकुल या गैर-क्लस्टर इंडेक्स का हिस्सा है, या अन्य गोचर जो सरल "जोड़ / निकालें / नाम बदलें" समाधान पर जा सकते हैं।

यहाँ चाल है: आप SQL सर्वर के परिवर्तन तालिका का उपयोग कर सकते हैं ... डेटा बदलने के बिना एक तालिका के स्कीमा को बदलने के लिए स्विच स्टेटमेंट, जिसका अर्थ है कि आप एक तालिका को एक समान तालिका स्कीमा के साथ एक पहचान पत्र के साथ बदल सकते हैं, लेकिन बिना पहचान स्तंभ के। एक मौजूदा कॉलम में IDENTITY को जोड़ने के लिए एक ही चाल काम करती है।

आम तौर पर, बेहतर तालिका ... किसी नए, खाली विभाजन के साथ एक विभाजन में पूर्ण विभाजन को कुशलतापूर्वक बदलने के लिए SWITCH का उपयोग किया जाता है। लेकिन इसका उपयोग गैर-विभाजन तालिकाओं में भी किया जा सकता है।

मैंने इस ट्रिक का उपयोग 5 सेकंड के भीतर, IDENTITY से गैर-पहचान (2.5 घंटे चलने के लिए एक बहु-स्तरीय क्वेरी चलाने के लिए किया है, जिसका क्वेरी प्लान नॉन-आइडेंटिटी के लिए बेहतर काम करता है। कॉलम), और फिर 5 सेकंड से भी कम समय में, पहचान सेटिंग को पुनर्स्थापित किया।

यह कैसे काम करता है इसका एक कोड नमूना है।

 CREATE TABLE Test
 (
   id int identity(1,1),
   somecolumn varchar(10)
 );

 INSERT INTO Test VALUES ('Hello');
 INSERT INTO Test VALUES ('World');

 -- copy the table. use same schema, but no identity
 CREATE TABLE Test2
 (
   id int NOT NULL,
   somecolumn varchar(10)
 );

 ALTER TABLE Test SWITCH TO Test2;

 -- drop the original (now empty) table
 DROP TABLE Test;

 -- rename new table to old table's name
 EXEC sp_rename 'Test2','Test';

 -- update the identity seed
 DBCC CHECKIDENT('Test');

 -- see same records
 SELECT * FROM Test; 

यह स्पष्ट रूप से अन्य उत्तरों में समाधान की तुलना में अधिक शामिल है, लेकिन अगर आपकी मेज बड़ी है तो यह वास्तविक जीवन रक्षक हो सकता है। कुछ चेतावनी हैं:

  • जहां तक ​​मुझे पता है, पहचान ही एकमात्र चीज है जो आप इस पद्धति से अपनी तालिका के स्तंभों के बारे में बदल सकते हैं। कॉलम जोड़ना / हटाना, अशक्तता बदलना, आदि की अनुमति नहीं है।
  • इससे पहले कि आप स्विच करें और बाद में उन्हें पुनर्स्थापित करें, आपको फ़ॉरेगन कीज़ को छोड़ना होगा।
  • समान कार्य, विचार आदि के लिए
  • नई तालिका के अनुक्रमित को बिल्कुल (समान कॉलम, समान आदेश, आदि) से मेल खाना चाहिए
  • पुराने और नए तालिकाओं को एक ही फाइलग्रुप पर होना चाहिए।
  • केवल SQL Server 2005 या बाद में काम करता है
  • मैं पहले मानता था कि यह ट्रिक SQL सर्वर के एंटरप्राइज़ या डेवलपर संस्करणों पर काम करती है (क्योंकि विभाजन केवल एंटरप्राइज़ और डेवलपर संस्करणों में समर्थित हैं), लेकिन नीचे दिए गए अपने टिप्पणी में मेसन जी। ज़्विती का कहना है कि यह SQL मानक संस्करण में भी काम करता है। मुझे लगता है कि इसका मतलब यह है कि एंटरप्राइज या डेवलपर के लिए प्रतिबंध AL TABLE ... SWITCH पर लागू नहीं होता है।

ऊपर की आवश्यकताओं का विवरण देते हुए टेकनेट पर एक अच्छा लेख है।

अद्यतन - एरिक वू ने नीचे एक टिप्पणी की थी जो इस समाधान के बारे में महत्वपूर्ण जानकारी जोड़ती है। यह सुनिश्चित करने के लिए कि यहां इसे और अधिक ध्यान दिया जाता है:

यहाँ एक और चेतावनी है जो ध्यान देने योग्य है। यद्यपि नई तालिका पुराने तालिका से खुशी से डेटा प्राप्त करेगी, और सभी नई पंक्तियों को एक पहचान पैटर्न के बाद डाला जाएगा, वे 1 पर शुरू होंगे और यदि संभावित रूप से उक्त स्तंभ एक प्राथमिक कुंजी है, तो वे टूट जाएंगे। DBCC CHECKIDENT('<newTableName>')स्विच करने के तुरंत बाद चलाने पर विचार करें । अधिक जानकारी के लिए msdn.microsoft.com/en-us/library/ms176057.aspx देखें ।

यदि तालिका सक्रिय रूप से नई पंक्तियों के साथ विस्तारित की जा रही है (जिसका अर्थ है कि आपके पास बहुत अधिक नहीं है अगर IDENTITY जोड़ने और नई पंक्तियों को जोड़ने के बीच कोई डाउनटाइम है, तो DBCC CHECKIDENTआप मैन्युअल रूप से नए तालिका स्कीमा में पहचान बीज मान सेट करना चाहते हैं मेज, जैसे की सबसे बड़ी मौजूदा आईडी से भी बड़ा IDENTITY (2435457, 1)। आप दोनों को शामिल करने में सक्षम हो सकता ALTER TABLE...SWITCHहै और DBCC CHECKIDENT(या not-- इस परीक्षण किया है नहीं) एक सौदे में लेकिन बीज मूल्य मैन्युअल रूप से स्थापित करने के आसान और सुरक्षित हो जाएगा की तरह लगता है।

जाहिर है, यदि तालिका में कोई नई पंक्तियों को नहीं जोड़ा जा रहा है (या वे केवल कभी-कभी, दैनिक ईटीएल प्रक्रिया की तरह जोड़े जाते हैं) तो यह दौड़ की स्थिति ठीक नहीं होगी DBCC CHECKIDENT


5
यदि मेरी मेमोरी सही है, तो मुझे इस लेख से विचार मिला: sqlservercentral.com/articles/T-SQL/61979
जस्टिन ग्रांट

2
FYI करें, यह SQL 2008 R2 के मानक संस्करण पर भी काम करता है। शायद उन्होंने इस सुविधा को वैसे ही सक्षम किया जैसे उन्होंने अब बैकअप संपीड़न को चालू करने की क्षमता को सक्षम किया है।
मेसन जी। ज़्विती

3
@jbatista - ओपी के प्रश्न में कहा गया है कि उनके पास पहले से ही मेज पर एक प्राथमिक कुंजी थी और पहले से ही सही मूल्यों को सुनिश्चित कर सकता था, लेकिन वह बस इसे एक पहचान कॉलम में बदलना चाहते थे। ऊपर दिया गया मेरा उत्तर उस संकीर्ण उपयोग-मामले पर केंद्रित है: वास्तव में किसी भी डेटा को बदलने के बिना एक कॉलम में पहचान को कैसे जोड़ा जाए। उपर्युक्त दृष्टिकोण मैं बड़ी तालिकाओं के लिए एक विशाल समय सेवर है। यदि आपको डेटा बदलने की आवश्यकता है, तो आपको अन्य समाधानों का उपयोग करने की आवश्यकता होगी।
जस्टिन ग्रांट

3
यहाँ एक और चेतावनी है जो ध्यान देने योग्य है। सोचा था कि नई तालिका पुरानी तालिका से खुशी से डेटा प्राप्त करेगी, और सभी नई पंक्तियों को एक पहचान पैटर्न के बाद डाला जाएगा , वे 1 पर शुरू होंगे और यदि संभावित रूप से उक्त स्तंभ एक प्राथमिक कुंजी है तो वे टूट जाएंगे। DBCC CHECKIDENT('<newTableName>')स्विच करने के तुरंत बाद चलाने पर विचार करें । अधिक जानकारी के लिए msdn.microsoft.com/en-us/library/ms176057.aspx देखें ।
एरिक वू

3
यह एक महान जवाब है! यह भी ध्यान दें कि स्तंभों की अशक्तता समान होनी चाहिए। इसलिए यदि आपको एक स्तंभ अशक्तता को बदलने की आवश्यकता है, तो आपको इसे बाद के चरण में करना होगा। वही पीके बाधाओं के लिए जाता है। मैं वर्तमान अधिकतम से मिलान करने के लिए तालिका निर्माण में पहचान मूल्य भी बदलता हूं: पहचान (अधिकतम + 1, 1)
फिलिप

71

आप एक स्तंभ को एक पहचान स्तंभ नहीं बदल सकते हैं। आपको जो करने की आवश्यकता होगी वह एक नया कॉलम बनाएगा जिसे गेट-गो से एक पहचान के रूप में परिभाषित किया गया है, फिर पुराने कॉलम को छोड़ दें, और नए को पुराने नाम पर नाम दें।

ALTER TABLE (yourTable) ADD NewColumn INT IDENTITY(1,1)

ALTER TABLE (yourTable) DROP COLUMN OldColumnName

EXEC sp_rename 'yourTable.NewColumn', 'OldColumnName', 'COLUMN'

न घुलनेवाली तलछट


या तो पैरामीटर \ @objname अस्पष्ट है या दावा किया गया @ @objtype (COLUMN) गलत है।
जेनी ओ'रेली

1
@ जेनी ओ'रेली: एक अलग सवाल में डाल दिया, और हमें पूरा कमांड दिखा रहे हैं जिसका आप उपयोग कर रहे हैं!
marc_s

2
यह sp_rename प्रक्रिया थी जो विफल हो रही थी। मुझे स्टैकओवरफ़्लो पर त्रुटि पाठ के लिए खोज करके एक समाधान मिला। यह कोष्ठक के साथ कुछ सख्त वाक्यविन्यास नियम लगता है, हालांकि मेरी तालिका में इसके नाम का कोई विशेष वर्ण नहीं है।
जेनी ओ'रेली

1
या ऐसा हो सकता है: 'ALTER TABLE (yourTable) DROP COLUMN OldColumnName' और 'ALTER TABLE (yourTable) ADD OldColumnName INT IDENTITY (1,1)', Why rename: p
RK Sharma

मार्क, मैंने एक विशाल टेबल (~ 300mln पंक्तियों) पर इस सटीक कमांड की कोशिश की, लेकिन मैंने ~ 10 मिनट के बाद प्रक्रिया रोक दी
नाओमी

14

यहाँ वर्णित शांत समाधान है: SQL सर्वर - स्तंभ पर पहचान संपत्ति जोड़ें या निकालें

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

यह विशाल समय बचाने वाला है, क्योंकि इसमें (स्क्रिप्ट) में आपके द्वारा परिवर्तित की गई तालिका से संबंधित सभी विदेशी कुंजियाँ, सूचकांक आदि शामिल हैं। इसे हाथ से लिखना ... भगवान न करे।


यह मेरे द्वारा उपयोग किया जाने वाला समाधान है - SSMS परिवर्तन करने के लिए T-SQL बनाता है ... यह एक ही स्कीमा डिज़ाइन की एक नई अस्थायी तालिका बनाकर करता है, फिर उसमें सभी पंक्तियों की प्रतिलिपि बनाकर, मूल को हटाकर और नाम बदल देता है । पूरी तरह से चलाने के लिए थोड़ा समय ले सकते हैं लेकिन यह पूरी तरह से काम करता है।
mdelvecchio

मुझे नहीं लगता कि पिनाल डेव वास्तव में कह रहे हैं कि आपको उस स्क्रिप्ट को चलाने की ज़रूरत है जो आप उत्पन्न करते हैं, यह सिर्फ यह दिखाना है कि यूआई के माध्यम से आपके लिए क्या बदलाव करना है ...
Zack

SSMS में यह स्क्रिप्टिंग फेसिअलिटी (एक टेबल की परिभाषा बदलने पर) वास्तव में विभाजन तालिका का दस्तावेजीकरण करते समय एकमात्र सही सुविधा है। सबसे उपयुक्त स्थान 'कार्य' -> 'स्क्रिप्ट तालिका' हमेशा विभाजन कार्य को स्क्रिप्ट करने के लिए भूल जाते हैं!
Martijn van der Jagt

1
किसी के लिए सहायक हो सकता है। परिवर्तन के बाद स्क्रिप्ट बदलने के लिए। SSMS पर डिज़ाइन मोड में तालिका पर राइट क्लिक करें और "जनरेट चेंज स्क्रिप्ट" विकल्प चुनें और स्क्रिप्ट को स्थानीय ड्राइव में सहेजें
विजई

11

पहचान की जगह SEQUENCE का उपयोग करने पर विचार करें ।

एसक्यूएल सर्वर 2014 (मुझे कम संस्करणों के बारे में नहीं पता है) आप अनुक्रम का उपयोग करके बस ऐसा कर सकते हैं।

CREATE SEQUENCE  sequence_name START WITH here_higher_number_than_max_existed_value_in_column INCREMENT BY 1;

ALTER TABLE table_name ADD CONSTRAINT constraint_name DEFAULT NEXT VALUE FOR sequence_name FOR column_name

यहां से: एक कॉलम के लिए डिफ़ॉल्ट मान के रूप में अनुक्रम


6

सरल व्याख्या

Sp_RENAME का उपयोग करके मौजूदा कॉलम का नाम बदलें

EXEC sp_RENAME 'Table_Name.Existing_ColumnName', 'New_ColumnName', 'COLUMN'

उदाहरण के लिए नाम बदलें:

मौजूदा कॉलम UserID को OldUserID नाम दिया गया है

EXEC sp_RENAME 'AdminUsers.UserID' , 'OldUserID', 'COLUMN'

फिर प्राथमिक कुंजी और पहचान मान के रूप में सेट करने के लिए परिवर्तन क्वेरी का उपयोग करके एक नया कॉलम जोड़ें

ALTER TABLE TableName ADD Old_ColumnName INT NOT NULL PRIMARY KEY IDENTITY(1,1)

सेट प्राथमिक कुंजी के लिए उदाहरण

नए बनाए गए कॉलम का नाम UserID है

ALTER TABLE Users ADD UserID INT NOT NULL PRIMARY KEY IDENTITY(1,1)

फिर नाम बदलें कॉलम ड्रॉप करें

ALTER TABLE Table_Name DROP COLUMN Renamed_ColumnName

उदाहरण के लिए ड्रॉप नामांकित कॉलम

ALTER TABLE Users DROP COLUMN OldUserID

अब हम टेबल पर मौजूदा कॉलम में एक प्राथमिक और पहचान जोड़ रहे हैं।


5

मैं एक जावा डेवलपर हूं जो एक डीबीए के बिना एक टीम पर प्राप्त करने के लिए हुआ है और जहां एक डेवलपर के रूप में, मुझे डीबीए अधिकार नहीं मिल सकता है। मुझे दो डेटाबेस के बीच पूरे स्कीमा को ले जाने का काम सौंपा गया था, इसलिए बिना डीबीए के, मुझे इसे करना पड़ा और स्क्रिप्ट चलाकर, SQL Server 2008 में GUI का उपयोग करने में सक्षम नहीं होने के कारण, क्योंकि मेरे पास व्यवस्थापक विशेषाधिकार नहीं थे।

सब कुछ समस्या के बिना स्थानांतरित कर दिया गया था, हालांकि, जब नए स्कीमा पर संग्रहित प्रक्रिया चल रही थी। तो, मैंने पाया कि मैंने एक तालिका में पहचान क्षेत्र खो दिया है। मैंने तालिका बनाने वाली स्क्रिप्ट को दोबारा जांचा और यह वहाँ था, हालाँकि, जब मैंने स्क्रिप्ट चलाई तो SQL सर्वर को यह नहीं मिला। मुझे बाद में एक डीबीए द्वारा बताया गया कि उसने पहले भी यही समस्या देखी थी।

किसी भी स्थिति में, SQL Server 2008 के लिए, ये ऐसे चरण हैं जो मैंने इसे हल करने के लिए उठाए हैं और उन्होंने काम किया है, इसलिए मैं इसे यहाँ पोस्ट कर रहा हूँ इस उम्मीद में कि यह किसी के लिए मददगार होगा। यह वही है जो मैंने किया था क्योंकि मेरे पास एक और मेज पर एफके निर्भरता थी जिसने इसे और अधिक कठिन बना दिया था:

पहचान को सत्यापित करने और तालिका पर निर्भरता देखने के लिए मैंने इस क्वेरी का उपयोग किया था।

1.) एक मेज पर आँकड़े खोजें:

exec sp_help 'dbo.table_name_old';

2.) पीके क्षेत्र पर एक पहचान फ़ील्ड को जोड़ने के लिए एक डुप्लिकेट, समान नई तालिका बनाएं, जहां वह पहले था।

3.) डेटा ले जाने के लिए पहचान को अक्षम करें।

SET IDENTITY_INSERT dbo.table_name ON 

4.) डेटा ट्रांसफर करें।

INSERT INTO dbo.table_name_new
(
field1, field2, etc...
)
SELECT 
field1, field2, etc...
FROM 
dbo.table_name_old;

5.) सत्यापित करें कि डेटा है।

SELECT * FROM dbo.table_name_new

6.) पहचान को फिर से सक्षम करें।

SET IDENTITY_INSERT ToyRecP.ToyAwards.lkpFile_New OFF

7.) यह सबसे अच्छी स्क्रिप्ट है जिसे मैंने सभी एफके रिश्तों को सत्यापित करने के लिए पाया कि कौन सी तालिका (एस) पर निर्भरता के रूप में मूल तालिका का संदर्भ है और मैं कई में आया हूं, इसलिए यह एक रक्षक है!

SELECT f.name AS ForeignKey,
   OBJECT_NAME(f.parent_object_id) AS TableName,
   COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName,
   OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
   COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc
   ON f.OBJECT_ID = fc.constraint_object_id
   ORDER BY ReferenceTableName;

8.) सुनिश्चित करें कि आपके पास अगले चरण से पहले सभी पीके और एफके लिपियों को शामिल करना है।

9.) आप SQL सर्वर 2008 का उपयोग करके प्रत्येक कुंजी और स्क्रिप्ट पर राइट-क्लिक कर सकते हैं

10.) इस सिंटैक्स का उपयोग करते हुए निर्भरता तालिका (ओं) से FK (ओं) को छोड़ें:

ALTER TABLE [dbo].[table_name] DROP CONSTRAINT [Name_of_FK]

11.) मूल तालिका छोड़ें:

DROP TABLE dbo.table_name_old;

13.) ये अगले चरण चरण 9 में SQL Server 2008 में आपके द्वारा बनाई गई स्क्रिप्ट पर निर्भर करते हैं।

- नई तालिका में पीके जोड़ें।

- नई तालिका में FK जोड़ें।

- निर्भरता तालिका में FK की पीठ जोड़ें।

14.) सत्यापित करें कि सब कुछ सही और पूर्ण है। मैंने तालिकाओं को देखने के लिए GUI का उपयोग किया।

15.) मूल तालिकाओं के नाम पर नई तालिका का नाम बदलें।

exec sp_RENAME '[Schema_Name.OldTableName]' , '[NewTableName]';

अंत में, सब कुछ काम किया!


4

आप ऐसा नहीं कर सकते, आपको एक और कॉलम जोड़ना होगा, मूल कॉलम को ड्रॉप करना होगा और नए कॉलम का नाम बदलना होगा या एक नया टेबल बनाना होगा, डेटा को कॉपी करना होगा और पुराने टेबल का नाम बदलने के बाद पुरानी टेबल को छोड़ना होगा। तालिका

यदि आप SSMS का उपयोग करते हैं और पहचान संपत्ति को डिज़ाइनर में चालू करते हैं तो यहाँ SQL सर्वर पर्दे के पीछे क्या करता है। इसलिए यदि आपके पास एक तालिका है जिसका नाम [उपयोगकर्ता] है तो उपयोगकर्ता और पहचान बनाने पर यही होता है

BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION

GO

GO
CREATE TABLE dbo.Tmp_User
    (
    UserID int NOT NULL IDENTITY (1, 1),
    LastName varchar(50) NOT NULL,
    FirstName varchar(50) NOT NULL,
    MiddleInitial char(1) NULL

    )  ON [PRIMARY]
GO

SET IDENTITY_INSERT dbo.Tmp_User ON
GO
IF EXISTS(SELECT * FROM dbo.[User])
 EXEC('INSERT INTO dbo.Tmp_User (UserID, LastName, FirstName, MiddleInitial)
    SELECT UserID, LastName, FirstName, MiddleInitialFROM dbo.[User] TABLOCKX')
GO
SET IDENTITY_INSERT dbo.Tmp_User OFF
GO

GO
DROP TABLE dbo.[User]
GO
EXECUTE sp_rename N'dbo.Tmp_User', N'User', 'OBJECT'
GO
ALTER TABLE dbo.[User] ADD CONSTRAINT
    PK_User PRIMARY KEY CLUSTERED 
    (
    UserID
    ) ON [PRIMARY]

GO
COMMIT

कहा कि बिटवाइज़ मान सेट करके सिस्टम टेबल को हैक करने का एक तरीका है, लेकिन यह समर्थित नहीं है और मैं इसे नहीं करूंगा


4

जैसा कि मैंने सामान्य मामलों में समझा था कि हम प्राथमिक कुंजी के साथ एक तालिका बना रहे हैं , जिसमें पहचान की संपत्ति है
इसलिए नाम बदलें या एक कॉलम हटाएं जो प्राथमिक कुंजी बाधा से जुड़ा हुआ है, यह संभव नहीं होगा क्योंकि बाधा नियम स्तंभ संरचना को मान्य कर रहे हैं।
इस हम निम्नलिखित तरीके से कुछ कदम पर कार्रवाई करने के लिए है को प्राप्त tto:
आइए हम मान लेते हैं TableName = 'कर्मचारी' और columnName = 'EmployeeID'

1. जोड़ें नया स्तंभ 'EmployeeId_new' 'कर्मचारी' तालिका में
ALTER तालिका कर्मचारी जोड़ें EmployeeId_new INT पहचान ( 1,1)

  1. अब 'EmployeeId' कॉलम को 'Employee' टेबल से हटा दें,
    TABLE T Employee DROP COLUMN EmployeeId

  2. प्राथमिक कुंजी बाधा नियम लागू होने और स्तंभ संरचना को मान्य करने के कारण यह त्रुटि फेंक देगा।
    * ### ' Msg 5074, लेवल 16, स्टेट 1, लाइन 1 ऑब्जेक्ट [PK_dbo.Employee] कॉलन [EmployeeId] पर निर्भर है।' ###

  3. इसलिए हमें प्राथमिक मुख्य बाधा को पहले 'कर्मचारी' से हटाना होगा फिर हम कॉलम को हटा सकते हैं
    कर्मचारी DROP बाधा [PK_dbo.Employee]

  4. अब हम 'कर्मचारी' तालिका से कॉलम 'EmployeeId' को हटा सकते हैं, जैसा कि पिछले चरण में किया गया था, जहाँ हमें त्रुटि के लिए
    TABLE Employee DROP COLUMN EmployeeId मिला था।

  5. अब कॉलम 'EmployeeId' को टेबल से हटा दिया गया है इसलिए हम नए जोड़े गए नए कॉलम 'EmployeeId_new' का नाम 'EmployeeId'
    sp_rename 'Employee.EmployeeId', 'EmployeeId_new', 'COLUMN' के साथ बदल देंगे।

  6. तालिका को उसी रूप में पुन: व्यवस्थित करने के लिए, हमें कॉलम 'EmployeeId' के लिए प्राथमिक कुंजी बाधा जोड़ना होगा '
    TABLE Employee जोड़ने के लिए बाधा [PK_dbo.Employee] प्राथमिक कुंजी (EmployeeId)

8. अब 'एंप्लॉयी' के साथ टेबल 'एम्प्लॉई' को मौजूदा प्राथमिक कुंजी बाधा के साथ पहचान नियमों के लिए संशोधित किया गया है।


3

डिज़ाइन के अनुसार मौजूदा कॉलम के लिए पहचान सुविधा को चालू या बंद करने का कोई सरल तरीका नहीं है। ऐसा करने का एकमात्र साफ तरीका यह है कि एक नया कॉलम बनाएं और इसे एक पहचान स्तंभ बनाएं या एक नई तालिका बनाएं और अपने डेटा को माइग्रेट करें।

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

परिवर्तन करने के लिए प्रबंधन स्टूडियो का उपयोग करें और फिर डिजाइनर में राइट क्लिक करें और "जनरेट चेंज स्क्रिप्ट" चुनें।

आप देखेंगे कि पृष्ठभूमि में यह SQL सर्वर है।


2

दुख की बात नहीं है; पहचान की संपत्ति स्तंभ के बजाय तालिका से संबंधित है।

इसका आसान तरीका यह है कि इसे GUI में किया जाए, लेकिन यदि यह विकल्प नहीं है, तो आप डेटा को कॉपी करने, कॉलम को छोड़ने, पहचान के साथ फिर से जोड़ने, और डेटा को वापस लाने के लिए लंबा रास्ता तय कर सकते हैं।

ब्लो-बाय-ब्लो अकाउंट के लिए यहां देखें ।


2

ऑब्जेक्ट एक्सप्लोरर में टेबल के नाम पर राइट क्लिक करें। आपको कुछ विकल्प मिलेंगे। 'डिजाइन' पर क्लिक करें। इस तालिका के लिए एक नया टैब खोला जाएगा। आप 'कॉलम गुण' में यहाँ पहचान की कमी जोड़ सकते हैं।


2

स्तंभ के लिए पहचान गुणों को संशोधित करने के लिए:

  • सर्वर एक्सप्लोरर में, पहचान गुणों के साथ तालिका को राइट-क्लिक करें जिसे आप संशोधित करना चाहते हैं और ओपन टेबल परिभाषा पर क्लिक करें। तालिका डिज़ाइनर में तालिका खुलती है।
  • जिस कॉलम को आप बदलना चाहते हैं, उसके लिए नल अनुमति दें चेक बॉक्स को साफ़ करें।
  • कॉलम गुण टैब में, पहचान विशिष्टता गुण का विस्तार करें।
  • आइडेंटिटी चाइल्ड प्रॉपर्टी के लिए ग्रिड सेल पर क्लिक करें और ड्रॉप-डाउन सूची से हां चुनें।
  • आइडेंटिटी सीड सेल में वैल्यू टाइप करें। यह मान तालिका में पहली पंक्ति को सौंपा जाएगा। मान 1 डिफ़ॉल्ट रूप से असाइन किया जाएगा।

यही है, और यह मेरे लिए काम किया


2

यदि आप Visual Studio 2017+ का उपयोग कर रहे हैं

  1. सर्वर ऑब्जेक्ट एक्सप्लोरर में अपनी टेबल पर राइट-क्लिक करें और "व्यू कोड" चुनें
  2. अपने कॉलम में संशोधक "पहचान" जोड़ें
  3. अपडेट करें

यह आपके लिए यह सब करेगा।


हाँ! यह सुझाव देने के लिए धन्यवाद! मेरे पास मेरे विंडोज 7 बॉक्स पर SSMS का एक संस्करण है, जो मुझे अपने प्रोडक्शन सर्वर पर टेबल में डिज़ाइन परिवर्तन करने की अनुमति देता है क्योंकि यह 2017 है, मेरा SSMS 2014 है, और 2017 SSMS को विंडोज 10. की आवश्यकता है। आपने मेरा दिन बना दिया। वीएस 2017 में चला गया> सर्वर एक्सप्लोरर> ने SQL सर्वर के उत्पादन के लिए एक नया कनेक्शन बनाया> टेबल पर राइट क्लिक किया> "ओपन टेबल डेफिनिशन"> वाल!
JustJohn

वास्तव में, मैंने पाया कि आप फ़ील्ड पर राइट क्लिक कर सकते हैं और प्रॉपर्टीज़ का चयन कर सकते हैं और वहाँ पर पहचान बना सकते हैं हाँ या नहीं
JustJohn

1

यदि मूल पोस्टर वास्तव PRIMARY KEYमें टेबल के लिए एक मौजूदा कॉलम सेट करना चाहता था और वास्तव में IDENTITYकॉलम (दो अलग-अलग चीजों) के लिए कॉलम की आवश्यकता नहीं थी, तो यह टी-एसक्यूएल के माध्यम से किया जा सकता है:

ALTER TABLE [YourTableName]
ADD CONSTRAINT [ColumnToSetAsPrimaryKey] PRIMARY KEY ([ColumnToSetAsPrimaryKey])

PRIMARY KEYविकल्प के बाद कॉलम नाम के चारों ओर कोष्ठक पर ध्यान दें ।

हालांकि यह पोस्ट पुरानी है और मैं अनुरोधकर्ताओं के बारे में एक धारणा बना रहा हूं, मुझे लगा कि यह अतिरिक्त जानकारी उपयोगकर्ताओं को इस थ्रेड का सामना करने में मददगार हो सकती है क्योंकि मेरा मानना ​​है कि बातचीत से किसी को विश्वास हो सकता है कि मौजूदा कॉलम को सेट नहीं किया जा सकता है प्राथमिक कुंजी बिना इसे नए कॉलम के रूप में जोड़े बिना जो गलत होगा।


1

अपनी वर्तमान स्थिति के अनुसार, मैं इस दृष्टिकोण का पालन करता हूं। मैं स्क्रिप्ट के माध्यम से डाले गए डेटा के बाद एक प्राथमिक तालिका को पहचान देना चाहता हूं।

जैसा कि मैं पहचान को बढ़ाना चाहता हूं, इसलिए यह हमेशा 1 से अंत तक रिकॉर्ड संख्या में शुरू होता है जो मुझे चाहिए।

--first drop column and add with identity
ALTER TABLE dbo.tblProductPriceList drop column ID 
ALTER TABLE dbo.tblProductPriceList add ID INT IDENTITY(1,1)

--then add primary key to that column (exist option you can ignore)
IF  NOT EXISTS (SELECT * FROM sys.key_constraints  WHERE object_id = OBJECT_ID(N'[dbo].[PK_tblProductPriceList]') AND parent_object_id = OBJECT_ID(N'[dbo].[tblProductPriceList]'))
    ALTER TABLE [tblProductPriceList] ADD PRIMARY KEY (id)
GO

यह पहचान के साथ एक ही प्राथमिक कुंजी कॉलम बनाएगा

मैंने इस लिंक का उपयोग किया: https://blog.sqlauthority.com/2014/10/11/sql-server-add-auto-incremental-identity-column-to-table-after-creating-table/

मौजूदा तालिका में प्राथमिक कुंजी जोड़ें


0

मुझे विश्वास नहीं है कि आप मौजूदा कॉलम को tsql का उपयोग करके एक पहचान कॉलम में बदल सकते हैं। हालाँकि, आप एंटरप्राइज़ प्रबंधक डिज़ाइन दृश्य के माध्यम से कर सकते हैं।

वैकल्पिक रूप से आप पहचान कॉलम के रूप में एक नई पंक्ति बना सकते हैं, पुराने कॉलम को छोड़ सकते हैं, फिर अपने नए कॉलम का नाम बदल सकते हैं।

ALTER TABLE FooTable
ADD BarColumn INT IDENTITY(1, 1)
               NOT NULL
               PRIMARY KEY CLUSTERED

2
ध्यान रखें कि यदि आप इसे SSMS / एंटरप्राइज़ मैनेजर के माध्यम से करते हैं - आप एक नई तालिका बना रहे होंगे, डेटा की प्रतिलिपि बना रहे होंगे, पुरानी तालिका को छोड़ देंगे, और नया नाम बदल देंगे। जब आप बड़ी टेबल रखते हैं तो यह काफी महंगा हो सकता है ...
स्कॉट Ivey

0

मूल रूप से चार तार्किक चरण हैं।

  1. एक नया पहचान स्तंभ बनाएं। इस नए कॉलम के लिए इंसर्ट आइडेंटिटी ऑन करें।

  2. इस नए कॉलम में डेटा को स्रोत कॉलम (आप जिस कॉलम को आइडेंटिटी में बदलना चाहते हैं) से डालें।

  3. नए कॉलम के लिए सम्मिलित पहचान बंद करें।

  4. अपने स्रोत कॉलम को ड्रॉप करें और स्रोत कॉलम के नाम पर नए कॉलम का नाम बदलें।

कुछ और जटिलताएँ हो सकती हैं जैसे कई सर्वरों पर काम करना आदि।

कृपया चरणों के लिए निम्नलिखित लेख देखें (ssms और T-sql का उपयोग करके)। ये कदम टी-एसक्यूएल पर कम पकड़ वाले शुरुआती लोगों के लिए अभिप्रेत हैं।

http://social.technet.microsoft.com/wiki/contents/articles/23816.how-to-convert-int-column-to-identity-in-the-ms-sql-server.aspx


0

प्राथमिक कुंजी = बिगिन के साथ सभी तालिकाओं के लिए एक स्क्रिप्ट उत्पन्न करता है जिसमें पहचान सेट नहीं होती है; यह प्रत्येक तालिका के साथ उत्पन्न स्क्रिप्ट की सूची लौटाएगा;

SET NOCOUNT ON;

declare @sql table(s varchar(max), id int identity)

DECLARE @table_name nvarchar(max),
        @table_schema nvarchar(max);

DECLARE vendor_cursor CURSOR FOR 
SELECT
  t.name, s.name
FROM sys.schemas AS s
INNER JOIN sys.tables AS t
  ON s.[schema_id] = t.[schema_id]
WHERE EXISTS (
    SELECT
    [c].[name]
    from sys.columns [c]
    join sys.types [y] on [y].system_type_id = [c].system_type_id
    where [c].[object_id] = [t].[object_id] and [y].name = 'bigint' and [c].[column_id] = 1
) and NOT EXISTS 
(
  SELECT 1 FROM sys.identity_columns
    WHERE [object_id] = t.[object_id]
) and exists (
    select 1 from sys.indexes as [i] 
    inner join sys.index_columns as [ic]  ON  i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id
    where object_name([ic].[object_id]) = [t].[name]
)
OPEN vendor_cursor

FETCH NEXT FROM vendor_cursor 
INTO @table_name, @table_schema

WHILE @@FETCH_STATUS = 0
BEGIN

DELETE FROM @sql

declare @pkname varchar(100),
    @pkcol nvarchar(100)

SELECT  top 1
        @pkname = i.name,
        @pkcol = COL_NAME(ic.OBJECT_ID,ic.column_id)
FROM    sys.indexes AS [i]
INNER JOIN sys.index_columns AS [ic] ON  i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id
WHERE   i.is_primary_key = 1 and OBJECT_NAME(ic.OBJECT_ID) = @table_name

declare @q nvarchar(max) = 'SELECT  '+@pkcol+' FROM ['+@table_schema+'].['+@table_name+'] ORDER BY '+@pkcol+' DESC'

DECLARE @ident_seed nvarchar(max) -- Change this to the datatype that you are after
SET @q = REPLACE(@q, 'SELECT', 'SELECT TOP 1 @output = ')
EXEC sp_executeSql @q, N'@output bigint OUTPUT', @ident_seed OUTPUT

insert into  @sql(s) values ('BEGIN TRANSACTION')
insert into  @sql(s) values ('BEGIN TRY')

-- create statement
insert into  @sql(s) values ('create table ['+@table_schema+'].[' + @table_name + '_Temp] (')

-- column list
insert into @sql(s) 
select 
    '  ['+[c].[name]+'] ' +
    y.name + 

    (case when [y].[name] like '%varchar' then
    coalesce('('+(case when ([c].[max_length] < 0 or [c].[max_length] >= 1024) then 'max' else cast([c].max_length as varchar) end)+')','')
    else '' end)

     + ' ' +
    case when [c].name = @pkcol then 'IDENTITY(' +COALESCE(@ident_seed, '1')+',1)' else '' end + ' ' +
    ( case when c.is_nullable = 0 then 'NOT ' else '' end ) + 'NULL ' + 
    coalesce('DEFAULT ('+(
        REPLACE(
            REPLACE(
                LTrim(
                    RTrim(
                        REPLACE(
                            REPLACE(
                                REPLACE(
                                    REPLACE(
                                        LTrim(
                                            RTrim(
                                                REPLACE(
                                                    REPLACE(
                                                        object_definition([c].default_object_id)
                                                    ,' ','~')
                                                ,')',' ')
                                            )
                                        )
                                    ,' ','*')
                                ,'~',' ')
                            ,' ','~')
                        ,'(',' ')
                    )
                )
            ,' ','*')
        ,'~',' ')
    ) +
    case when object_definition([c].default_object_id) like '%get%date%' then '()' else '' end
    +
    ')','') + ','
 from sys.columns c
 JOIN sys.types y ON y.system_type_id = c.system_type_id
  where OBJECT_NAME(c.[object_id]) = @table_name and [y].name != 'sysname'
 order by [c].column_id


 update @sql set s=left(s,len(s)-1) where id=@@identity

-- closing bracket
insert into @sql(s) values( ')' )

insert into @sql(s) values( 'SET IDENTITY_INSERT ['+@table_schema+'].['+@table_name+'_Temp] ON')

declare @cols nvarchar(max)
SELECT @cols = STUFF(
    (
        select ',['+c.name+']'
        from sys.columns c
        JOIN sys.types y ON y.system_type_id = c.system_type_id
        where c.[object_id] = OBJECT_ID(@table_name)
        and [y].name != 'sysname'
        and [y].name != 'timestamp'
        order by [c].column_id
        FOR XML PATH ('')
     )
    , 1, 1, '')

insert into @sql(s) values( 'IF EXISTS(SELECT * FROM ['+@table_schema+'].['+@table_name+'])')
insert into @sql(s) values( 'EXEC(''INSERT INTO ['+@table_schema+'].['+@table_name+'_Temp] ('+@cols+')')
insert into @sql(s) values( 'SELECT '+@cols+' FROM ['+@table_schema+'].['+@table_name+']'')')

insert into @sql(s) values( 'SET IDENTITY_INSERT ['+@table_schema+'].['+@table_name+'_Temp] OFF')


insert into @sql(s) values( 'DROP TABLE ['+@table_schema+'].['+@table_name+']')

insert into @sql(s) values( 'EXECUTE sp_rename N''['+@table_schema+'].['+@table_name+'_Temp]'', N'''+@table_name+''', ''OBJECT''')

if ( @pkname is not null ) begin
    insert into @sql(s) values('ALTER TABLE ['+@table_schema+'].['+@table_name+'] ADD CONSTRAINT ['+@pkname+'] PRIMARY KEY CLUSTERED (')
    insert into @sql(s)
        select '  ['+COLUMN_NAME+'] ASC,' from information_schema.key_column_usage
        where constraint_name = @pkname
        GROUP BY COLUMN_NAME, ordinal_position
        order by ordinal_position

    -- remove trailing comma
    update @sql set s=left(s,len(s)-1) where id=@@identity
    insert into @sql(s) values ('  )')
end

insert into  @sql(s) values ('--Run your Statements')
insert into  @sql(s) values ('COMMIT TRANSACTION')
insert into  @sql(s) values ('END TRY')
insert into  @sql(s) values ('BEGIN CATCH')
insert into  @sql(s) values ('        ROLLBACK TRANSACTION')
insert into  @sql(s) values ('        DECLARE @Msg NVARCHAR(MAX)  ')
insert into  @sql(s) values ('        SELECT @Msg=ERROR_MESSAGE() ')
insert into  @sql(s) values ('        RAISERROR(''Error Occured: %s'', 20, 101,@msg) WITH LOG')
insert into  @sql(s) values ('END CATCH')

declare @fqry nvarchar(max)

-- result!
SELECT @fqry = (select char(10) + s from @sql order by id FOR XML PATH (''))


SELECT @table_name as [Table_Name], @fqry as [Generated_Query]
PRINT 'Table: '+@table_name
EXEC sp_executeSql @fqry

    FETCH NEXT FROM vendor_cursor 
    INTO @table_name, @table_schema
END 
CLOSE vendor_cursor;
DEALLOCATE vendor_cursor;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.