PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Bagaimana cara mengubah ID tabel dari serial menjadi identitas?

BEGIN;
ALTER TABLE public.client ALTER clientid DROP DEFAULT; -- drop default

DROP SEQUENCE public.client_clientid_seq;              -- drop owned sequence

ALTER TABLE public.client
-- ALTER clientid SET DATA TYPE int,                   -- not needed: already int
   ALTER clientid ADD GENERATED ALWAYS AS IDENTITY (RESTART 108);
COMMIT;

Ada dua variabel:

  • nama sebenarnya dari SEQUENCE terlampir . Saya menggunakan nama default di atas, tetapi namanya bisa berbeda.
  • nilai maksimum saat ini di client.clientid . Tidak harus 107, hanya karena saat ini ada 107 baris.

Kueri ini mendapatkan keduanya:

SELECT pg_get_serial_sequence('client', 'clientid'), max(clientid) FROM client;

Sebuah serial kolom adalah integer kolom yang dimiliki urutan khusus dan memiliki set default untuk menggambar darinya (seperti yang dapat dilihat dari definisi tabel yang Anda posting). Untuk membuatnya menjadi integer biasa , hapus defaultnya, lalu hapus urutannya.

Mengubah kolom menjadi IDENTITY menambahkan urutannya sendiri. Anda harus jatuhkan urutan lama yang dimiliki (atau setidaknya kepemilikan, yang mati dengan menjatuhkan urutan). Jika tidak, Anda mendapatkan kesalahan seperti:

Bagaimana cara menyalin struktur dan isi tabel, tetapi dengan urutan terpisah?

Kemudian konversikan integer biasa kolom ke IDENTITY kolom, dan mulai ulang dengan maksimum saat ini plus 1 . Anda harus atur nilai saat ini dari urutan internal baru untuk menghindari pelanggaran unik.

Bungkus semuanya dalam satu transaksi, sehingga Anda tidak mengacaukan setengah jalan dalam migrasi. Semua perintah DDL ini bersifat transaksional di Postgres, dapat dibatalkan hingga dilakukan dan hanya dapat dilihat oleh transaksi lain yang dimulai setelah itu.

Kolom Anda adalah PK sebelumnya dan tetap PK. Ini ortogonal terhadap perubahan.

Peter Eisentraut, penulis utama dari (baru di Postgres 10) IDENTITY fitur, juga menyediakan fungsi upgrade_serial_to_identity() untuk mengonversi serial yang ada kolom. Ini menggunakan kembali urutan yang ada dan sebagai gantinya memperbarui katalog sistem secara langsung - yang tidak boleh Anda lakukan sendiri kecuali Anda tahu persis apa yang Anda lakukan. Ini juga mencakup kasus sudut eksotis. Lihat (bab "Meningkatkan versi"):

Namun, fungsi tersebut tidak akan berfungsi pada sebagian besar layanan yang dihosting yang tidak mengizinkan manipulasi langsung katalog sistem. Kemudian Anda kembali ke perintah DDL seperti yang diinstruksikan di atas.

Terkait:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgres:perintah vakum tidak membersihkan tupel yang mati

  2. Mengapa tipe data char dikonversi ke bpchar secara otomatis?

  3. Optimalkan kueri dengan OFFSET di meja besar

  4. PostgreSQL generate_series() dengan fungsi SQL sebagai argumen

  5. Bagaimana cara saya mencatat pernyataan SQL di Vapor 3/Fluent?