2009-08-07 14 views
44

Jak dodać nową kolumnę do tabeli za drugą lub trzecią kolumną w tabeli używając postgreS?Jak dodać nową kolumnę do tabeli za drugą lub trzecią kolumną w tabeli, używając postgreS?

Mój kod wygląda następująco

ALTER TABLE n_domains ADD COLUMN contract_nr int after owner_id 
+2

Kolejność kolumn jest całkowicie nieistotna w relacyjnych bazach danych - to tylko kwestia ich wyświetlenia w narzędziu. Tabela bazy danych nie ma żadnego uporządkowania kolumn. –

Odpowiedz

49

Nie, nie ma bezpośredni sposób to zrobić. I jest ku temu powód - każde zapytanie powinno zawierać wszystkie potrzebne pola w dowolnej kolejności (i formacie itp.), Które ich potrzebują, co sprawia, że ​​kolejność kolumn w jednej tabeli jest niewielka.

Jeśli naprawdę trzeba zrobić, że mogę myśleć o jednego rozwiązania:

  • zrzutu i zapisać opis tabeli w pytaniu (używając pg_dump --schema-only --table=<schema.table> ...)
  • dodać kolumnę, którą chcesz, gdzie chcesz zapisanego w definicji
  • zmienić nazwę tabeli zapisanej definicji tak, aby nie kolidować z nazwą starym stole, gdy spróbujesz go utworzyć
  • utworzyć nową tabelę przy użyciu tej definicji
  • zapełnij nową tabelę danymi ze starej tabeli, używając "INSERT INTO <new_table> SELECT field1, field2, <default_for_new_field>, field3, ... FROM <old_table>";
  • zmień starą tabelę
  • zmienić nazwę nowej tabeli do oryginalnej nazwy
  • ostatecznie spaść stary, przemianowane tabelę po upewnić, że wszystko jest w porządku
+12

"każde zapytanie powinno zawierać wszystkie potrzebne pola w dowolnej kolejności" - to proste, o ile nie będziesz musiał pracować z innymi ludźmi. –

+9

Kolejność kolumn może być nieistotna dla aplikacji korzystającej z bazy danych. Dla DBA wyglądałoby o wiele ładniej, gdyby podobne kolumny były wymienione w kolejności podczas badania struktury tabeli lub danych. Osobiście uważam za irytujące, że mam kilka kolumn czasowych, które nie są pogrupowane wizualnie, ponieważ zostały dodane później. Ponowne utworzenie bazy danych tylko dlatego, że Postgres nie obsługuje dodawania kolumny na określonej pozycji, wydaje mi się dziwne, szczególnie jeśli powodem jest zmuszenie ludzi do jawnego wyświetlania kolumn w swoich zapytaniach. Aby było jasne: nie uważam, że to jest powód. – Dynom

-3

Kolejność kolumn jest całkowicie bez znaczenia w relacyjnych bazach danych

Tak.

Na przykład, jeśli używasz Python, zrobiłbyś:

cursor.execute("SELECT id, name FROM users") 
for id, name in cursor: 
    print id, name 

Albo zrobisz:

cursor.execute("SELECT * FROM users") 
for row in cursor: 
    print row['id'], row['name'] 

Ale nikt przy zdrowych zmysłach nigdy używać pozycyjnych wyniki tak:

cursor.execute("SELECT * FROM users") 
for id, name in cursor: 
    print id, name 
+9

To jest całkowicie nieprawdziwe. Działa to w celu wybrania sposobu wyświetlania, ale często nie jest widoczne wstawianie bez określonych nazw kolumn, np. wstawić do wartości w tabeli (1, 2, 3, 4). Jeśli lista kolumn kolumnowych ulegnie zmianie, to ten styl kwerendy wstawiania nie powiedzie się. Warto również zauważyć, że nie każdy programista jest przyzwoity i jeśli przypadkiem odziedziczysz kod od jednego z tych programistów ... –

21

Kolejność kolumn nie jest bez znaczenia, ustawienie kolumn o stałej szerokości z przodu tabeli może decydować naśladując układ przechowywania danych, może również ułatwić pracę z danymi poza kodem aplikacji.

PostgreSQL nie obsługuje zmiany kolejności kolumn (patrz Alter column position na wiki PostgreSQL); Jeśli tabela jest stosunkowo odosobnione, najlepiej jest, aby odtworzyć tabelę:

CREATE TABLE foobar_new (...); 
INSERT INTO foobar_new SELECT ... FROM foobar; 
DROP TABLE foobar CASCADE; 
ALTER TABLE foobar_new RENAME TO foobar; 

Jeśli masz wiele poglądów i ograniczeń określonych na stole, można ponownie dodać wszystkie kolumny po nowej kolumny i upuść oryginalne kolumny (zobacz przykładową wiki PostgreSQL).

-1

@ Rozwiązanie Jeremy Gustie powyżej prawie działa, ale zrobi coś złego, jeśli liczby porządkowe są wyłączone (lub zawodzą, jeśli ponownie zamówione porządki sprawiają, że niezgodne typy pasują do siebie). Spróbować:

CREATE TABLE test1 (one varchar, two varchar, three varchar); 
CREATE TABLE test2 (three varchar, two varchar, one varchar); 
INSERT INTO test1 (one, two, three) VALUES ('one', 'two', 'three'); 
INSERT INTO test2 SELECT * FROM test1; 
SELECT * FROM test2; 

Wyniki pokazują problem:

testdb=> select * from test2; 
three | two | one 
-------+-----+------- 
one | two | three 
(1 row) 

Można temu zaradzić poprzez podanie nazwy kolumn we wkładce:

INSERT INTO test2 (one, two, three) SELECT * FROM test1; 

który daje ci to, czego naprawdę chcesz:

testdb=> select * from test2; 
three | two | one 
-------+-----+----- 
three | two | one 
(1 row) 

Problem pojawia się, gdy masz spuściznę, która tego nie robi, jak wskazałem powyżej w moim komentarzu do odpowiedzi peufeu.

Aktualizacja: Przyszło mi do głowy, że można zrobić to samo z nazwami kolumn w klauzuli INSERT poprzez podanie nazwy kolumn w klauzuli SELECT. Po prostu trzeba uporządkować je dopasować porządkowych w tabeli docelowej:

INSERT INTO test2 SELECT three, two, one FROM test1; 

I można oczywiście wykonać obie są bardzo wyraźne:

INSERT INTO test2 (one, two, three) SELECT one, two, three FROM test1; 

To daje takie same wyniki jak wyżej, z prawidłowo dopasowanymi wartościami kolumn.

-2

@ Milen A. Radev

nie mające związku z potrzeby posiadania ustawioną kolejność kolumn nie zawsze jest określona przez zapytanie, które ich ciągnie. W wartościach od pg_fetch_row nie ma powiązanej nazwy kolumny, dlatego też kolumny powinny być zdefiniowane przez instrukcję SQL.

Prosta select * from wymagałaby znajomości struktury tabeli i czasami powodowała problemy w przypadku zmiany kolejności kolumn.

Stosowanie jest bardziej niezawodną metodą, ponieważ można odwoływać się do nazw kolumn, a zatem używać prostego select * from.

+1

Ta potrzeba nie jest bez znaczenia. Kiedy ręcznie sprawdzam dane, chcę użyć po prostu 'SELECT *', a jednak chcę, aby bardziej interesujące kolumny były na pierwszym miejscu. – maaartinus

Powiązane problemy