2008-09-24 4 views
19

क्या पोस्टग्रेस 8.1 में कॉलम के प्राकृतिक क्रम को बदलना संभव है?क्या पोस्टग्रेस में कॉलम के प्राकृतिक क्रम को बदलना संभव है?

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

उत्तर

18

आप वास्तव में सीधे कॉलम ऑर्डर बदल सकते हैं, लेकिन मैं शायद ही इसकी अनुशंसा करता हूं, और यदि आप इसे करने का निर्णय लेते हैं तो आपको बहुत सावधान रहना चाहिए।

उदाहरण के लिए।

 
# CREATE TABLE test (a int, b int, c int); 
# INSERT INTO test VALUES (1,2,3); 
# SELECT * FROM test; 
a | b | c 
---+---+--- 
1 | 2 | 3 
(1 row) 

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

 
# SELECT relname, relfilenode FROM pg_class WHERE relname='test'; 
relname | relfilenode 
---------+------------- 
test_t |  27666 
(1 row) 

# SELECT attrelid, attname, attnum FROM pg_attribute WHERE attrelid=27666; 
attrelid | attname | attnum 
----------+----------+-------- 
    27666 | tableoid |  -7 
    27666 | cmax  |  -6 
    27666 | xmax  |  -5 
    27666 | cmin  |  -4 
    27666 | xmin  |  -3 
    27666 | ctid  |  -1 
    27666 | b  |  1 
    27666 | a  |  2 
    27666 | c  |  3 
(9 rows) 

attnum एक अद्वितीय स्तंभ है, तो आप जब आप इस तरह के रूप स्तंभ संख्या संशोधित कर रहे हैं एक अस्थायी मान का उपयोग करने की जरूरत है:,

 
# UPDATE pg_attribute SET attnum=4 WHERE attname='a' AND attrelid=27666; 
UPDATE 1 
# UPDATE pg_attribute SET attnum=1 WHERE attname='b' AND attrelid=27666; 
UPDATE 1 
# UPDATE pg_attribute SET attnum=2 WHERE attname='a' AND attrelid=27666; 
UPDATE 1 

# SELECT * FROM test; 
b | a | c 
---+---+--- 
1 | 2 | 3 
(1 row) 

फिर क्योंकि इस डेटाबेस प्रणाली तालिकाओं के साथ चारों ओर खेल रहा है , अगर आपको लगता है कि आपको वास्तव में ऐसा करने की ज़रूरत है तो अत्यधिक सावधानी बरतें।

यह postgres 8.3 के रूप में काम कर रहा है, पहले के संस्करण के साथ, अपने लाभ भिन्न हो सकते।

+4

यह बहुत मुश्किल है, कई सिस्टम ऑब्जेक्ट कॉलम नंबर का संदर्भ लेते हैं। जब आप कॉलम 2 और 3 फ्लिप करते हैं, तो किसी ऑब्जेक्ट को कॉलम 2 से कुछ चाहिए तो आपको परेशानी होगी। यह अब nr 3 और आपका डेटाबेस है अब भ्रष्ट है। pg_constraint पर एक नज़र डालें, यह डेटाबेस सेवर हो सकता है। –

+3

इस तरह आप अपने टैब में सभी डेटा खो देते हैं लेस। –

+5

असमर्थित होने के अलावा, यह तकनीक कॉलम नामों को उनकी सामग्री के सम्मान के बिना स्वैप करती है, जो (उत्तर स्वीकार किए जाने के बावजूद) सवाल नहीं पूछ रहा है। और यदि वह इसके लिए पूछ रहा था, 'वैकल्पिक तालिका ... नाम COLUMN ...' का उपयोग इसके बजाय किया जाना चाहिए, क्योंकि यह एक ही परिणाम प्राप्त करता है लेकिन भरोसेमंद। –

0

दुर्भाग्य से, नहीं, ऐसा नहीं है। कॉलम ऑर्डर पूरी तरह पोस्टग्रेस तक है।

1

क्वेरी में कॉलम ऑर्डर निर्दिष्ट करना केवल विश्वसनीय (और सौहार्दपूर्ण) तरीका है। उस ने कहा, आप आमतौर पर नीचे दिए गए उदाहरण में दिखाए गए तालिका को बदलकर एक अलग क्रम प्राप्त कर सकते हैं क्योंकि कॉलम आमतौर पर तालिका में जोड़े गए क्रम में लौटाए जाते हैं (गारंटी नहीं दी जाती)।

postgres=# create table a(a int, b int, c int); 
CREATE TABLE 
postgres=# insert into a values (1,2,3); 
INSERT 0 1 
postgres=# select * from a; 
a | b | c 
---+---+--- 
1 | 2 | 3 
(1 row) 

postgres=# alter table a add column a2 int; 
ALTER TABLE 
postgres=# select * from a; 
a | b | c | a2 
---+---+---+---- 
1 | 2 | 3 | 
(1 row) 

postgres=# update a set a2 = a; 
UPDATE 1 
postgres=# alter table a drop column a; 
ALTER TABLE 
postgres=# alter table a rename column a2 to a; 
ALTER TABLE 
postgres=# select * from a; 
b | c | a 
---+---+--- 
2 | 3 | 1 
(1 row) 

postgres=# 
+0

मैं एक प्रश्न नहीं लिख रहा हूं। मैं ऐसे उत्पाद का उपयोग कर रहा हूं जो प्रश्नों और रूपों और सामानों को स्वतः उत्पन्न करता है। इसे उत्पन्न होने के बाद मैं इसे संपादित कर सकता हूं, लेकिन मैं फिर से पुन: उत्पन्न करने में सक्षम हूं और फिर से संपादित नहीं करना चाहता हूं। – rjmunro

+0

तो एक तरह से स्तंभ आदेश निर्दिष्ट करने के लिए के बारे में उत्पाद प्रदाता से पूछें (या पूछना वे एक विशेषता के रूप में जोड़ने) –

+0

IIRC Postgresql डेवलपर्स है, इस सुविधा :( – grom

3

जैसा कि अन्य उत्तरों का उल्लेख है, आप कॉलम के क्रम को नहीं बदल सकते हैं, जो पोस्टग्रेज़ तक है। आप अपनी समस्या को एक दृश्य के साथ हल कर सकते हैं (और चाहिए!)। आपकी रिपोर्टिंग क्वेरी के प्रयोजनों के लिए, यह एक टेबल की तरह दिखेगा। कुछ की तरह:

create view my_view as 
    select * from my_table 
    order by some_col; 
+2

कि कॉलम के क्रम नहीं बदल रहा है न जोड़ना जो बदल रही है एक स्तंभ के आधार पर डेटा के आदेश। – rjmunro

12

तो अपने डेटाबेस बहुत बड़ा नहीं है और आप फिर कुछ डाउनटाइम बर्दाश्त कर सकते हैं आप कर सकते हैं:

  1. डेटाबेस के लिए लेखन पहुँच अक्षम
    इस के बाद अन्यथा कोई भी परिवर्तन के रूप में आवश्यक है से शुरू करके अगले बिंदु खो जाएगा
  2. pg_dump --create --column-inserts databasename > databasename.pgdump.sql
  3. संपादित apropriate CREATE TABLE databa में बयान sename.pgdump.sql
    तो फ़ाइल अपने संपादक के लिए बहुत बड़ा है बस इसे split आदेश, संपादित का उपयोग कर विभाजित करते हैं, तो का उपयोग कर वापस इकट्ठा cat
  4. drop database databasename
    आप हाल ही में एक बैकअप है सिर्फ मामले में, क्या आप?
  5. psql --single-transaction -f databasename.pgdump.sql
    आप --single-transaction उपयोग नहीं करते हैं यह बहुत धीमी गति से

हो जाएगा तुम इतनी बड़ी वस्तुओं सुनिश्चित करें कि वे डंप में शामिल कर रहे हैं कहा जाता है का उपयोग करते हैं। मुझे यकीन नहीं है कि वे डिफ़ॉल्ट रूप से 8.1 में हैं या नहीं।

+0

यह 9.3 के साथ बहुत अच्छी तरह से काम करता है। ध्यान दें कि आप डंप फ़ाइल में तीन लाइनों कि डेटाबेस नाम का उल्लेख बदल सकते हैं अगर आप एक नए डेटाबेस में आयात करना चाहते हैं। –

+0

के साथ अच्छी तरह से काम करता है 9.6.1 भी – docesam

7

मैं 2007 में टॉम लेन pgsql-व्यवस्थापक में यह सवाल पूछा है खुद यह व्यावहारिक रूप से अव्यावहारिक कैटलॉग में क्रम बदलने के लिए की घोषणा की। स्पष्टीकरण: .. मौजूदा उपकरणों के साथ उपयोगकर्ताओं के लिए (अभी भी v9.1 के लिए सच है)। इसका मतलब यह नहीं है कि इसे लागू नहीं किया जा सका। आईएमओ, यह होना चाहिए।

CREATE TABLE test_new AS SELECT b, c, a FROM test; 
SELECT * from test_new; 
b | c | a 
---+---+--- 
2 | 3 | 1 
(1 row) 

नोट इस प्रतियां डेटा है कि:
http://archives.postgresql.org/pgsql-admin/2007-06/msg00037.php

+2

"कॉलम स्थिति के पुन: क्रम की अनुमति देने का विचार पोस्टग्रेस्क्ल डेवलपर्स के खिलाफ नहीं है, यह एक ऐसा मामला है जहां कोई भी काम करने के लिए आगे बढ़ता नहीं है।" से उद्धरण http://wiki.postgresql.org/wiki/Alter_column_position यदि कोई उस कार्यक्षमता को जोड़ना चाहता है ... प्रारंभिक चरणों को लेख के अंत में उल्लिखित किया गया है। उस पर –

+2

+1, हालांकि मुझे लगता है कि हर कोई इसके बारे में जानता है। इगोर नेमैन की प्रतिक्रिया से, कुछ के लिए इसका कोई कारण नहीं है। मुझे लगता है कि यह सुविधा अक्सर होती है जब यह सुविधा उपयोगी होती है, esp। अपने जैसे ओसीडी-इन-स्कीमा लोगों के लिए। जैसा कि टॉम लेन ने बताया, हमें "विचार, विदेशी कुंजी, अनुक्रमणिका, डिफ़ॉल्ट, नियम इत्यादि" भी बदलना होगा। और अन्य सभी चीजें कॉलम पर निर्भर हैं। वास्तव में यह पीएल/पीजीएसक्यूएल का उपयोग करके भी अकल्पनीय प्रतीत नहीं होता है। मुझे लगता है कि हम में से अधिकांश इस समस्या पर ठोकर खा रहे हैं जैसे "अगर मेरे पास समय था।" –

0

आप है कि आप उन्हें प्रस्तुत करना चाहते हैं स्तंभ आदेश है कि आप एक नया टेबल बनाने और क्रम में वर्ष तालिका के कॉलम का चयन करके चाहते प्राप्त कर सकते हैं केवल, नहीं संशोधक, बाधाओं, अनुक्रमित, आदि ..

एक बार नई तालिका आपके संशोधित किया गया है, मूल ड्रॉप और नए एक का नाम बदल:

BEGIN; 
DROP TABLE test; 
ALTER TABLE test_new RENAME TO test; 
COMMIT; 
0

मैं एक ही इच्छुक हूँ। हाँ, यह अब अनिवार्य आदेश है, लेकिन यह सिर्फ मुझे गलत तरीके से :)

क्या मैं इसे इस प्रकार है हल करने के लिए कर रहा हूँ की मालिश।

इस विधि आप किसी भी मौजूदा डेटा रखने को सुनिश्चित करेगा,

  1. आदेश मैं चाहता हूँ का उपयोग कर तालिका का एक नया संस्करण बनाने के लिए, एक अस्थायी नाम इस्तेमाल करते हैं।
  2. मौजूदा डेटा से उस नई तालिका में सभी डेटा डालें।
  3. पुरानी तालिका ड्रॉप करें।
  4. "अस्थायी नाम" से "उचित नाम" के लिए नए तालिका का नाम।
  5. आपके द्वारा पहले की गई किसी भी अनुक्रमणिका को फिर से जोड़ें। प्राथमिक कुंजी वेतन वृद्धि के लिए
  6. रीसेट आईडी अनुक्रम।

वर्तमान तालिका आदेश:

id, name, email 

1. आदेश मैं चाहता हूँ का उपयोग कर तालिका का एक नया संस्करण बनाने के लिए, एक अस्थायी नाम इस्तेमाल करते हैं।

इस उदाहरण में, मुझे emailname से पहले होना चाहिए।

CREATE TABLE mytable_tmp 
(
    id SERIAL PRIMARY KEY, 
    email text, 
    name text 
); 

मौजूदा एक से 2. सम्मिलित है कि नई तालिका में सभी डेटा।

INSERT INTO mytable_tmp --- << new tmp table 
(
    id 
, email 
, name 
) 
SELECT 
    id 
, email 
, name 
FROM mytable; --- << this is the existing table 

3. ड्रॉप वर्ष मेज।

DROP TABLE mytable; 

4. "अस्थायी नाम" से "उचित नाम" के लिए नए तालिका का नाम।

ALTER TABLE mytable_tmp RENAME TO mytable; 

5. किसी भी अनुक्रमित आपने पहले फिर से जोड़ें। प्राथमिक कुंजी वेतन वृद्धि के लिए

CREATE INDEX ... 

6. रीसेट आईडी अनुक्रम।

SELECT setval('public.mytable_id_seq', max(id)) FROM mytable;