ALTER TABLE în PostgreSQL

Tabele, scheme și tipuri (DDL) PostgreSQL 8.0+ (ADD COLUMN IF NOT EXISTS: 9.6+)

Modifică un tabel existent: adaugă, șterge sau redenumește coloane, schimbă tipul, valoarea implicită și constrângerile.

Sintaxă SQL
ALTER TABLE [IF EXISTS] nume
    ADD COLUMN [IF NOT EXISTS] coloana tip [constrângeri]
  | DROP COLUMN [IF EXISTS] coloana [CASCADE]
  | ALTER COLUMN coloana TYPE tip [USING expresie]
  | ALTER COLUMN coloana SET DEFAULT valoare | DROP DEFAULT
  | ALTER COLUMN coloana SET NOT NULL | DROP NOT NULL
  | RENAME COLUMN vechi TO nou
  | RENAME TO nume_nou
  | ADD CONSTRAINT nume constrângere [NOT VALID]
  | VALIDATE CONSTRAINT nume
  | DROP CONSTRAINT nume;

Ce face ALTER TABLE

ALTER TABLE schimbă structura unui tabel fără să-l creezi din nou. Mai multe modificări se pot face într-o singură comandă, separate prin virgulă.

Unele modificări sunt instantanee, altele rescriu tot tabelul. Adăugarea unei coloane cu o valoare implicită constantă este rapidă din PostgreSQL 11. Schimbarea tipului (ALTER COLUMN ... TYPE) rescrie de obicei tabelul și îl blochează pe durata operației: pe tabele mari, planific-o când traficul este mic.

Pentru constrângeri noi pe tabele mari există NOT VALID: constrângerea se aplică imediat rândurilor noi, iar cele vechi se verifică separat cu VALIDATE CONSTRAINT, care blochează mai puțin.

Parametri

Parametru Descriere
ADD COLUMN Adaugă o coloană. Rândurile existente primesc valoarea DEFAULT sau NULL.
DROP COLUMN Șterge coloana și datele ei. CASCADE șterge și obiectele care depind de ea (view-uri, indecși).
ALTER COLUMN ... TYPE ... USING Schimbă tipul. USING spune cum se convertesc valorile vechi.
SET / DROP NOT NULL Adaugă sau scoate regula „nu poate fi gol”.
RENAME COLUMN / RENAME TO Redenumește o coloană, respectiv tabelul.
ADD CONSTRAINT ... NOT VALID Adaugă o constrângere fără să verifice rândurile existente.

Ce returnează

Mesajul ALTER TABLE.

Exemple

Exemplul 1: Coloane noi și redenumiri

ALTER TABLE clienti
    ADD COLUMN telefon text,
    ADD COLUMN activ boolean NOT NULL DEFAULT true;

ALTER TABLE clienti RENAME COLUMN nume TO nume_complet;
ALTER TABLE clienti ADD COLUMN IF NOT EXISTS telefon text;

Rezultat în psql

ALTER TABLE
ALTER TABLE
NOTICE:  column "telefon" of relation "clienti" already exists, skipping
ALTER TABLE

Exemplul 2: Schimbarea tipului unei coloane

Coloana cod_postal era text. Fără USING, PostgreSQL nu știe cum să transforme textul în număr.

ALTER TABLE clienti ALTER COLUMN cod_postal TYPE integer;
ALTER TABLE clienti ALTER COLUMN cod_postal TYPE integer USING cod_postal::integer;

Rezultat în psql

ERROR:  column "cod_postal" cannot be cast automatically to type integer
HINT:  You might need to specify "USING cod_postal::integer".
ALTER TABLE

Exemplul 3: NOT NULL pe o coloană cu goluri și constrângere NOT VALID

ALTER TABLE clienti ALTER COLUMN telefon SET NOT NULL;

ALTER TABLE comenzi ADD CONSTRAINT total_pozitiv CHECK (total >= 0) NOT VALID;
ALTER TABLE comenzi VALIDATE CONSTRAINT total_pozitiv;

Rezultat în psql

ERROR:  column "telefon" of relation "clienti" contains null values
ALTER TABLE
ALTER TABLE

Greșeli frecvente

  • Schimbi tipul unei coloane pe un tabel de zeci de milioane de rânduri în timpul zilei. Tabelul este rescris și blocat; aplicația așteaptă.
  • Redenumești o coloană folosită de aplicație sau de funcții. View-urile se actualizează singure, dar codul aplicației și funcțiile scrise ca text (PL/pgSQL) nu.
  • Adaugi SET NOT NULL înainte să completezi valorile lipsă: rulează mai întâi un UPDATE ... WHERE coloana IS NULL.

Comenzi înrudite

  • CREATE TABLE: Creează un tabel nou, cu coloane, tipuri de date și constrângeri: PRIMARY KEY, NOT NULL, UNIQUE, CHECK, DEFAULT, FOREIGN KEY.
  • DROP TABLE: Șterge definitiv un tabel, cu toate datele, indecșii, triggerele și constrângerile lui.
  • FOREIGN KEY (REFERENCES): Cheia străină leagă două tabele: valoarea dintr-o coloană trebuie să existe în tabelul părinte, iar ON DELETE spune ce se întâmplă la ștergere.
  • CREATE VIEW: Salvează o interogare sub un nume, ca s-o folosești ca pe un tabel. Datele nu se copiază: interogarea rulează la fiecare citire.