PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come modificare un ID tabella da seriale a identità?

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;

Ci sono due variabili:

  • il nome effettivo del SEQUENCE allegato . Ho usato il nome predefinito sopra, ma il nome può essere diverso.
  • il valore massimo corrente in client.clientid . Non deve essere 107, solo perché attualmente ci sono 107 righe.

Questa query ottiene entrambi:

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

Un serial colonna è un integer colonna che proprietario una sequenza dedicata e ha il suo set predefinito per attingere da essa (come si può vedere dalla definizione della tabella che hai pubblicato). Per renderlo un semplice integer , rilascia l'impostazione predefinita e quindi rilascia la sequenza.

Conversione della colonna in un IDENTITY aggiunge la propria sequenza. devi abbandonare la vecchia sequenza di proprietà (o almeno la proprietà, che muore con l'eliminazione della sequenza). Altrimenti ricevi errori come:

Come copiare la struttura e il contenuto di una tabella, ma con sequenza separata?

Quindi converti il ​​semplice integer colonna a un IDENTITY colonna e ricominciare con il massimo corrente più 1 . devi imposta il valore corrente della nuova sequenza interna per evitare violazioni univoche.

Avvolgi tutto in un'unica transazione, così non sbagli a metà della migrazione. Tutti questi comandi DDL sono transazionali in Postgres, possono essere ripristinati fino al commit e sono visibili solo ad altre transazioni che iniziano dopo.

La tua colonna era prima PK e rimane PK. Questo è ortogonale al cambiamento.

Peter Eisentraut, l'autore principale del (nuovo in Postgres 10) IDENTITY funzione, forniva anche una funzione upgrade_serial_to_identity() per convertire il serial esistente colonne. Riutilizza la sequenza esistente e invece aggiorna direttamente i cataloghi di sistema, cosa che non dovresti fare da solo a meno che tu non sappia esattamente cosa stai facendo. Copre anche casi d'angolo esotici. Dai un'occhiata (capitolo "Aggiornamento"):

Tuttavia, la funzione non funzionerà sulla maggior parte dei servizi ospitati che non consentono la manipolazione diretta dei cataloghi di sistema. Quindi sei tornato ai comandi DDL come indicato in alto.

Correlati: