sql >> Database >  >> RDS >> PostgreSQL

Hoe verander ik een tabel-ID van serieel naar identiteit?

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;

Er zijn twee variabelen:

  • de werkelijke naam van de bijgevoegde SEQUENCE . Ik heb de standaardnaam hierboven gebruikt, maar de naam kan verschillen.
  • de huidige maximale waarde in client.clientid . Hoeft geen 107 te zijn, alleen omdat er momenteel 107 rijen zijn.

Deze zoekopdracht krijgt beide:

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

Een serial kolom is een integer kolom die bezit een speciale reeks en is standaard ingesteld om daaruit te tekenen (zoals te zien is in de tabeldefinitie die u hebt gepost). Om er een gewoon integer van te maken , laat de standaardwaarde vallen en laat de reeks vallen.

De kolom converteren naar een IDENTITY voegt zijn eigen volgorde toe. Je moet laat de oude eigendomsreeks vallen (of op zijn minst het eigendom, dat sterft door de reeks te laten vallen). Anders krijg je fouten zoals:

Hoe kopieer ik de structuur en inhoud van een tabel, maar met een aparte volgorde?

Converteer vervolgens het gewone integer kolom naar een IDENTITY kolom en start opnieuw met het huidige maximum plus 1 . Je moet stel de huidige waarde van de nieuwe interne reeks in om unieke schendingen te voorkomen.

Verpak het allemaal in één enkele transactie, zodat u niet halverwege de migratie verprutst. Al deze DDL-opdrachten zijn transactioneel in Postgres, kunnen worden teruggedraaid totdat ze zijn vastgelegd en zijn alleen zichtbaar voor andere transacties die daarna beginnen.

Uw column was voorheen PK en blijft PK. Dit staat loodrecht op de wijziging.

Peter Eisentraut, de hoofdauteur van de (nieuw in Postgres 10) IDENTITY functie, leverde ook een functie upgrade_serial_to_identity() om bestaande serial te converteren kolommen. Het hergebruikt de bestaande volgorde en werkt in plaats daarvan rechtstreeks systeemcatalogi bij - wat u niet zelf zou moeten doen, tenzij u precies weet wat u doet. Het dekt ook exotische hoekkasten. Bekijk het (hoofdstuk "Upgraden"):

De functie werkt echter niet op de meeste gehoste services die directe manipulatie van systeemcatalogi niet toestaan. Dan ben je terug bij de DDL-commando's zoals bovenaan aangegeven.

Gerelateerd:



  1. Oracle - retourneer meerdere tellingen als één query

  2. Meerdere rijen invoegen in MySQL

  3. zoek het aantal rijen in het geretourneerde mysql-resultaat (nodejs)

  4. hoe variabele van shellscript door te geven aan sqlplus