Bagaimana cara menambahkan kunci primer penambahan otomatis ke tabel yang ada, di PostgreSQL?

190

Saya punya tabel dengan data yang ada. Apakah ada cara untuk menambahkan kunci utama tanpa menghapus dan membuat ulang tabel?

xRobot
sumber

Jawaban:

355

( Diperbarui - Terima kasih kepada orang-orang yang berkomentar )

Versi Modern PostgreSQL

Misalkan Anda memiliki tabel bernama test1, yang ingin Anda tambahkan idkolom penambahan-kunci, kunci utama (pengganti). Perintah berikut harus mencukupi di versi terbaru PostgreSQL:

   ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;

Versi PostgreSQL yang lebih lama

Dalam versi PostgreSQL lama (sebelum 8.x?) Anda harus melakukan semua pekerjaan kotor. Urutan perintah berikut harus melakukan trik:

  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');

Sekali lagi, dalam versi terbaru Postgres ini kira-kira sama dengan perintah tunggal di atas.

leonbloy
sumber
3
Saya menggunakan ORACLE, jadi membagikannya mungkin berguna bagi orang-orang ORACLE Di ORACLE: ALTER TABLE TEST1 TAMBAHKAN ID NOMOR; UPDATE TEST1 SET ID = TEST1_SEQ.NEXTVAL; ALTER TABLE TEST1 TAMBAHKAN KUNCI UTAMA (ID); buat Sequence TEST1_SEQ sebelum menjalankan pernyataan UPDATE
msbyuva
Catatan yang ADD PRIMARY KEYjuga menciptakan NOT NULLkendala (diuji di postgres 9.3) seperti yang diharapkan dan diinginkan.
Jared Beck
19
Di Postgres Anda dapat menggunakan perintah tunggalALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;
resnyanskiy
1
Lebih jauh lagi ke komentar @ resnyanskiy, ini akan berfungsi bahkan ketika ada data di tabel. ID diisi dan bukan batasan nol yang ditetapkan. Seluruh jawaban dapat diganti dengan baris di komentar itu.
Synesso
1
@EricWang Terima kasih, Eric, Anda benar - saya percaya ini tidak berfungsi beberapa versi (tahun) yang lalu, tapi saya tidak yakin. Mengubah jawabannya menjadi komunitas-wiki.
leonbloy
57
ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;

Ini yang Anda butuhkan untuk:

  1. Tambahkan idkolom
  2. Populasikan dengan urutan dari 1 hingga hitungan (*).
  3. Atur sebagai kunci utama / bukan nol.

Penghargaan diberikan kepada @resnyanskiy yang memberikan jawaban ini dalam komentar.

Synesso
sumber
2
Ini harus ditandai sebagai jawaban, dan jawabannya harus menjadi milik @resnyanskiy
Eric Wang
Saya harus menjatuhkan kuncinya terlebih dahulu dan kemudian menjalankannya. ALTER TABLE <table> DROP CONSTRAINT <pkey_name>;
Josh Robertson
10

Untuk menggunakan kolom identitas di v10,

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

Untuk penjelasan tentang kolom identitas, lihat https://blog.2ndquadrant.com/postgresql-10-identity-columns/ .

Untuk perbedaan antara DIHASILKAN OLEH DEFAULT dan SELALU DIHASILKAN, lihat https://www.cybertec-postgresql.com/en/ followingences-gains-and-pitfalls / .

Untuk mengubah urutan, lihat https://popsql.io/learn-sql/postgresql/how-to-alter- berikutnyaence-in-postgresql/ .

jhoanna
sumber
Masalah dengan solusi ini adalah bahwa jika tabel sudah berisi baris maka Anda mendapatkan kesalahan:SQL Error [23502]: ERROR: column "id" contains null values
isapir
3
@ mengisapir: Ada bug di versi awal (hal 10 dan 10.1) yang menghasilkan kesalahan ini. Itu diperbaiki dengan hal 10.2. Detail di sini: dba.stackexchange.com/q/200143/3684
Erwin Brandstetter
Terima kasih @ erwin-brandstetter
isapir
Setahun kemudian saya menemukan jawaban ini lagi, bug yang tampaknya diperbaiki,
terbalik
2

Saya mendarat di sini karena saya mencari sesuatu seperti itu juga. Dalam kasus saya, saya menyalin data dari seperangkat tabel pementasan dengan banyak kolom menjadi satu tabel sementara juga menetapkan id baris ke tabel target. Berikut adalah varian dari pendekatan di atas yang saya gunakan. Saya menambahkan kolom serial di akhir tabel target saya. Dengan begitu saya tidak perlu memiliki placeholder untuk itu dalam pernyataan Sisipkan. Kemudian pilih * sederhana ke tabel target secara otomatis mengisi kolom ini. Berikut adalah dua pernyataan SQL yang saya gunakan pada PostgreSQL 9.6.4.

ALTER TABLE target ADD COLUMN some_column SERIAL;
INSERT INTO target SELECT * from source;
Dean Sha
sumber