sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur ändrar man ett tabell-ID från seriell till 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;

Det finns två variabler:

  • det faktiska namnet på den bifogade SEQUENCE . Jag använde standardnamnet ovan, men namnet kan skilja sig åt.
  • det nuvarande maxvärdet i client.clientid . Behöver inte vara 107, bara för att det för närvarande finns 107 rader.

Den här frågan får båda:

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

En serial kolumnen är ett integer kolumn som äger en dedikerad sekvens och har sin standardinställning för att dra från den (som kan ses av tabelldefinitionen du postade). För att göra det till ett vanligt integer , släpp standardvärdet och släpp sedan sekvensen.

Konverterar kolumnen till en IDENTITY lägger till sin egen sekvens. Du måste släpp den gamla ägda sekvensen (eller åtminstone ägandet, som dör när sekvensen släpps). Annars får du felmeddelanden som:

Hur kopierar man struktur och innehåll i en tabell, men med separat sekvens?

Konvertera sedan det vanliga integer kolumn till en IDENTITY kolumn och starta om med nuvarande maximala plus 1 . Du måste ställ in det aktuella värdet för den nya interna sekvensen för att undvika unika överträdelser.

Slå in allt i en enda transaktion så att du inte krånglar halvvägs in i migreringen. Alla dessa DDL-kommandon är transaktionsbaserade i Postgres, kan återställas tills de har begåtts och är endast synliga för andra transaktioner som börjar efter det.

Din kolumn var PK innan och förblir PK. Detta är ortogonalt mot förändringen.

Peter Eisentraut, huvudförfattaren till (ny i Postgres 10) IDENTITY funktion, även en funktion upgrade_serial_to_identity() för att konvertera befintlig serial kolumner. Den återanvänder den befintliga sekvensen och uppdaterar istället systemkataloger direkt - vilket du inte bör göra själv om du inte vet exakt vad du gör. Den täcker även exotiska hörnfodral. Kolla in det (kapitlet "Uppgradering"):

Funktionen fungerar dock inte på de flesta värdtjänster som inte tillåter direkt manipulering av systemkataloger. Sedan är du tillbaka till DDL-kommandon enligt instruktionerna överst.

Relaterat:



  1. Hur synkroniserar och optimerar man ett Oracle Text-index?

  2. Hur man uppdaterar flera kolumner i PostgreSQL

  3. Vad är det bästa sättet att paginera resultat i SQL Server

  4. SQL Server Failover Cluster Installation -3