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

Hvordan ændrer man et tabel-id fra seriel til identitet?

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;

Der er to variable:

  • det faktiske navn på den vedhæftede SEQUENCE . Jeg brugte standardnavnet ovenfor, men navnet kan variere.
  • den aktuelle maksimumværdi i client.clientid . Behøver ikke at være 107, bare fordi der i øjeblikket er 107 rækker.

Denne forespørgsel får begge:

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

En serial kolonne er et integer kolonne, der ejer en dedikeret sekvens og har sin standardindstilling til at trække fra den (som det kan ses af den tabeldefinition, du har sendt). For at gøre det til et almindeligt integer , slip standarden og slip derefter sekvensen.

Konvertering af kolonnen til en IDENTITY tilføjer sin egen sekvens. Du skal droppe den gamle ejede sekvens (eller i det mindste ejerskabet, som dør ved at droppe sekvensen). Ellers får du fejl som:

Hvordan kopieres struktur og indhold af en tabel, men med separat sekvens?

Konverter derefter det almindelige integer kolonne til en IDENTITY kolonne, og genstart med det nuværende maksimum plus 1 . Du skal indstille den aktuelle værdi af den nye interne sekvens for at undgå unikke overtrædelser.

Pak det hele i en enkelt transaktion, så du ikke roder halvvejs ind i migreringen. Alle disse DDL-kommandoer er transaktionelle i Postgres, kan rulles tilbage, indtil de er forpligtet og er kun synlige for andre transaktioner, der starter derefter.

Din kolonne var PK før og forbliver PK. Dette er ortogonalt i forhold til ændringen.

Peter Eisentraut, hovedforfatteren af ​​(nyt i Postgres 10) IDENTITY funktion, også en funktion upgrade_serial_to_identity() at konvertere eksisterende serial kolonner. Den genbruger den eksisterende sekvens og opdaterer i stedet systemkataloger direkte - hvilket du ikke bør gøre selv, medmindre du ved præcis, hvad du laver. Det dækker også eksotiske hjørnetasker. Tjek det ud (kapitel "Opgradering"):

Funktionen virker dog ikke på de fleste hostede tjenester, der ikke tillader direkte manipulation af systemkataloger. Så er du tilbage til DDL-kommandoer som anvist øverst.

Relateret:



  1. Brug af meteor med postgresql

  2. KGXGN polling fejl (15)

  3. Er der nogen forskel mellem varchar(10) og varchar(1000), når vi gemmer streng, hvis længde er mindre end 10?

  4. Søg efter en bestemt streng i Oracle clob-kolonnen