PostgreSQL में मौजूदा तालिका में एक ऑटो-इन्क्रिमिंग प्राथमिक कुंजी कैसे जोड़ें?


190

मेरे पास मौजूदा डेटा वाली एक तालिका है। क्या टेबल को हटाने और फिर से बनाने के बिना एक प्राथमिक कुंजी जोड़ने का एक तरीका है?

जवाबों:


354

( अपडेट किया गया ( टिप्पणी करने वाले लोगों के लिए धन्यवाद )

PostgreSQL के आधुनिक संस्करण

मान लें कि आपके पास एक तालिका है test1, जिसका नाम आप एक ऑटो-इंक्रीमेंट, प्राथमिक-कुंजी id(सरोगेट) कॉलम जोड़ना चाहते हैं । निम्न कमांड PostgreSQL के हाल के संस्करणों में पर्याप्त होना चाहिए:

   ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;

PostgreSQL के पुराने संस्करण

PostgreSQL के पुराने संस्करणों में (8.x से पहले?) आपको सभी गंदे काम करने थे। कमांड के निम्नलिखित अनुक्रम को चाल करना चाहिए:

  ALTER TABLE test1 ADD COLUMN id INTEGER;
  CREATE SEQUENCE test_id_seq OWNED BY test1.id;
  ALTER TABLE test ALTER COLUMN id SET DEFAULT nextval('test_id_seq');
  UPDATE test1 SET id = nextval('test_id_seq');

फिर से, Postgres के हाल के संस्करणों में यह ऊपर दिए गए एकल आदेश के लगभग बराबर है।


3
मैं ORACLE का उपयोग कर रहा हूं, इसलिए इसे ORACLE में ORACLE लोगों के लिए साझा करना उपयोगी हो सकता है: TTER1 TEST1 ADD ID NUMBER; अद्यतन TEST1 सेट ID = TEST1_SEQ.NEXTVAL; अन्य तालिका TEST1 ADD PRIMARY KEY (ID); UPDATE स्टेटमेंट को निष्पादित करने से पहले एक अनुक्रम TEST1_SEQ बनाएं
msbyuva

ध्यान दें कि उम्मीद और वांछित के रूप में ADD PRIMARY KEYएक NOT NULLबाधा भी बनती है (9.3 पोस्टग्रेट्स में परीक्षण)।
जारेड बेक

19
Postgres में आप सिंगल कमांड का उपयोग कर सकते हैंALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;
resnyanskiy

1
इसके अलावा @ resnyanskiy की टिप्पणी, यह तब भी काम करेगा जब तालिका में डेटा हो। आईडी आबाद हैं और अशक्त नहीं है। उस टिप्पणी में पूरे उत्तर को लाइन से बदला जा सकता है।
साइनेसियो

1
@ EricWang धन्यवाद, एरिक, आप सही हैं - मेरा मानना ​​है कि यह कुछ संस्करणों (वर्षों) पहले काम नहीं किया था, लेकिन मुझे यकीन नहीं है। जवाब को समुदाय-विकि में बदल दिया।
leonbloy

57
ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;

यह आप सभी की जरूरत है:

  1. idकॉलम जोड़ें
  2. इसे 1 (गिनती) के अनुक्रम से पॉप्युलेट करें।
  3. इसे प्राथमिक कुंजी के रूप में सेट करें / शून्य नहीं।

श्रेय @resnyanskiy को दिया जाता है जिन्होंने एक टिप्पणी में यह जवाब दिया था।


2
यह उत्तर के रूप में चिह्नित किया जाना चाहिए, और उत्तर @resnyanskiy से संबंधित होना चाहिए
एरिक वांग

मुझे पहले प्याऊ को गिराना था और फिर इसे चलाना था। ALTER TABLE <table> DROP CONSTRAINT <pkey_name>;
जोश रॉबर्टसन

10

V10 में एक पहचान कॉलम का उपयोग करने के लिए,

ALTER TABLE test 
ADD COLUMN id { int | bigint | smallint}
GENERATED { BY DEFAULT | ALWAYS } AS IDENTITY PRIMARY KEY;

पहचान कॉलम की व्याख्या के लिए, https://blog.2ndquadrant.com/postgresql-10-identity-columns/ देखें

डीफ़ॉल्ट और जेनरेट किए गए ALWAYS द्वारा जेनरेट किए गए अंतर के लिए, https://www.cybertec-postgresql.com/en/fterences-gains-and-pitashes/ देखें

अनुक्रम को बदलने के लिए, https://popsql.io/learn-sql/postgresql/how-to-alter-fterence-in-postgresql/ देखें


इस समाधान के साथ समस्या यह है कि यदि तालिका में पहले से ही पंक्तियाँ हैं तो आपको एक त्रुटि मिलती है:SQL Error [23502]: ERROR: column "id" contains null values
isapir

3
@isapir: इस त्रुटि को उत्पन्न करने वाले प्रारंभिक संस्करणों (पृष्ठ 10 और 10.1) में एक बग था। यह पृष्ठ 10.2 के साथ तय किया गया था। यहाँ विवरण: dba.stackexchange.com/q/200143/3684
एरविन ब्रान्डेसटेटर

धन्यवाद @ erwin-brandstetter
isapir

एक साल बाद मुझे यह उत्तर फिर से मिला, बग स्पष्ट रूप से तय हुआ,
उखाड़ा

2

मैं यहां इसलिए उतरा क्योंकि मुझे भी कुछ ऐसा ही लग रहा था। मेरे मामले में, मैं एक तालिका में कई स्तंभों के साथ स्टैगिंग तालिकाओं के सेट से डेटा को कॉपी कर रहा था, जबकि लक्ष्य तालिका में पंक्ति आईडी भी निर्दिष्ट कर रहा था। यहाँ उपर्युक्त दृष्टिकोणों का एक प्रकार है जो मैंने उपयोग किया था। मैंने अपने लक्ष्य तालिका के अंत में सीरियल कॉलम जोड़ा। इस तरह मुझे डालने के बयान में इसके लिए एक प्लेसहोल्डर नहीं होना चाहिए। तब लक्ष्य तालिका ऑटो में एक सरल चयन * इस कॉलम को आबाद करता है। यहाँ दो एसक्यूएल स्टेटमेंट हैं जो मैंने पोस्टग्रेक्यूएल 9.6.4 पर उपयोग किए थे।

ALTER TABLE target ADD COLUMN some_column SERIAL;
INSERT INTO target SELECT * from source;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.