ALTER TABLE

Nom

ALTER TABLE -- change la définition d'une table

Synopsis

ALTER TABLE [ ONLY ] nom [ * ]
    action [, ... ]
ALTER TABLE [ ONLY ] nom [ * ]
    RENAME [ COLUMN ] colonne TO nouvelle_colonne
ALTER TABLE nom
    RENAME TO nouveau_nomaction fait partie de :

    ADD [ COLUMN ] colonne
type [ contrainte_colonne [ ... ] ]
    DROP [ COLUMN ] colonne [
RESTRICT | CASCADE ]
    ALTER [ COLUMN ] colonne TYPE
type [ USING expression ]
    ALTER [ COLUMN ] colonne SET
DEFAULT expression
    ALTER [ COLUMN ] colonne DROP
DEFAULT
    ALTER [ COLUMN ] colonne { SET
| DROP } NOT NULL
    ALTER [ COLUMN ] colonne SET
STATISTICS entier
    ALTER [ COLUMN ] colonne SET
STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
    ADD contrainte_table
    DROP CONSTRAINT nom_contrainte
[ RESTRICT | CASCADE ]
    CLUSTER ON nom_index
    SET WITHOUT CLUSTER
    SET WITHOUT OIDS
    OWNER TO nouveau_proprietaire
    SET TABLESPACE nom_espacelogique

Description

ALTER TABLE change la définition d'une table existante. Il existe plusieurs variantes :

ADD COLUMN

Cette variante ajoute une nouvelle colonne à la table en utilisant la même syntaxe que CREATE TABLE.

DROP COLUMN

Cette variante supprime une colonne d'une table. Les index et les contraintes de table référençant cette colonne sont automatiquement supprimés. Il faut utiliser l'option CASCADE si certains objets hors de la table dépendent de cette colonne, comme par exemple des références de clés étrangères ou des vues.

ALTER COLUMN TYPE

Cette variante modifie le type d'une colonne de la table. Les index et les contraintes de table simples impliquant la colonne seront automatiquement convertis pour utiliser le nouveau type de la colonne en réanalysant l'expression fournie au départ. La clause USING optionnelle spécifie comment calculer la nouvelle valeur de la colonne à partir de l'ancienne ; en cas d'omission, la conversion par défaut est identique à une affectation de l'ancien type vers le nouveau. Une clause USING doit être fournie s'il n'existe pas de conversion implicite de l'ancien vers le nouveau type.

SET/DROP DEFAULT

Ces variantes ajoutent ou enlèvent des valeurs par défaut pour une colonne. Ces valeurs par défaut ne s'appliquent qu'aux prochaines commandes INSERT. Elles ne modifient pas les lignes déjà présentes dans la table. Des valeurs par défaut peuvent aussi être créées pour les vues. Dans ce cas, elles sont ajoutées aux commandes INSERT de la vue avant que la règle ON INSERT de la vue ne soit appliquée.

SET/DROP NOT NULL

Ces variantes changent le fait que la colonne indique autoriser les valeurs NULL ou non. SET NOT NULL ne peut être utilisé que si la colonne ne contient pas de valeurs NULL.

SET STATISTICS

Cette variante permet de modifier l'objectif de collecte de statistiques par colonne pour les opérations d'analyse (ANALYZE) à venir. L'objectif prend une valeur entre 0 et 1000. Le mettre à -1 pour utiliser l'objectif de statistiques par défaut du système (default_statistics_target). Pour plus d'informations sur l'utilisation des statistiques par le planificateur de requêtes de PostgreSQL, référez-vous à Section 13.2.

SET STORAGE

Ces variantes changent le mode de stockage pour une colonne. Cela permet de contrôler si cette colonne est gardée en ligne dans la table ou bien externalisée dans une table supplémentaire, et si les données doivent être compressées ou non. PLAIN doit être utilisé pour les valeurs de longueur fixe, comme les integer et est en ligne non compressé. MAIN est pour les données en ligne compressibles. EXTERNAL est pour les données externes non compressées. EXTENDED est pour les données externes compressées. EXTENDED est la valeur par défaut pour la plupart des types qui supportent les autres stockages que PLAIN. Utiliser EXTERNAL rendra les opérations d'extraction de sous-chaînes text et bytea plus rapides mais utilisera plus d'espace de stockage. Notez que SET STORAGE ne modifie rien dans la table, il configure la stratégie à poursuivre lors des prochaines mises à jour de tables. Voir Section 49.2 pour plus d'informations.

ADD contrainte_table

Cette variante ajoute une nouvelle contrainte à une table en utilisant la même syntaxe que CREATE TABLE.

DROP CONSTRAINT

Cette forme supprime les contraintes d'une table. Actuellement, les contraintes des tables n'ont pas besoin d'avoir des noms uniques, donc il pourrait y avoir plus d'une correspondance de contraintes pour le nom spécifié. Toutes les contraintes correspondantes seront supprimées.

CLUSTER

Cette variante sélectionne l'index par défaut pour les prochaines opérations CLUSTER. Il ne ré-exécute pas la commande CLUSTER.

SET WITHOUT CLUSTER

Cette variante supprime la spécification d'index CLUSTER la plus récemment utilisée à partir de cette table. Ceci affecte les prochaines opérations CLUSTER qui ne spécifient pas d'index.

SET WITHOUT OIDS

Cette variante supprime la colonne système oid de la table. Ceci est strictement équivalent à DROP COLUMN oid RESTRICT, sauf qu'il ne se plaindra pas s'il existe déjà une colonne oid.

Notez qu'il n'existe pas de variante de ALTER TABLE qui autoriserait la restauration des OID d'une table, une fois ceux-ci supprimés.

OWNER

Cette variante change le propriétaire d'une table, d'un index, d'une séquence, ou d'une vue. Le nouveau propriétaire est celui passé en paramètre.

SET TABLESPACE

Cette forme modifie le tablespace de la table par le tablespace spécifié et déplace le(s) fichier(s) de données associé(s) avec la table vers le nouveau tablespace. Les index de la table, s'il y en a, ne sont pas déplacés ; mais ils peuvent l'être séparément avec des commandes SET TABLESPACE supplémentaires. Voir aussi CREATE TABLESPACE.

RENAME

La forme RENAME modifie le nom d'une table (ou d'un index, séquence ou vue) ou le nom d'une colonne individuelle d'une table. Elle n'a aucun effet sur la donnée stockée.

Toutes les actions à l'exception de RENAME peuvent être combinées dans une liste de plusieurs altérations à appliquer en parallèle. Par exemple, il est possible d'ajouter plusieurs colonnes et/ou modifier le type de plusieurs colonnes en une seule commande. Ceci est particulièrement utile avec les grosses tables car seule une passe sur la table sera nécessaire.

Il faut être propriétaire de la table pour utiliser ALTER TABLE, sauf pour ALTER TABLE OWNER, qui ne peut être utilisée que par un super utilisateur.

Paramètres

nom

Le nom (éventuellement précisé par un schéma) d'une table existante, que l'on veut modifier. Si ONLY est indiqué, cette table seulement est modifiée. Si ONLY est absent, alors la table et toutes ses tables filles (s'il y en a) sont modifiées. * peut être ajouté au nom de la table pour indiquer que ses tables descendantes doivent être modifiées. Dans la version courante, c'est le comportement par défaut. Dans les versions antérieures à la 7.1, ONLY était le comportement par défaut. Le comportement par défaut peut être modifié en changeant le paramètre de configuration sql_inheritance.

colonne

Nom d'une colonne existante ou nouvelle.

nouvelle_colonne

Nouveau nom d'une colonne existante.

nouveau_nom

Nouveau nom de la table.

type

Type de donnée de la nouvelle colonne, ou nouveau type de données d'une colonne existante.

contraintedetable

Nouvelle contrainte de table pour la table.

nomdecontrainte

Nom d'une contrainte existante à supprimer

CASCADE

Supprime automatiquement les objets dépendant de la colonne ou contrainte supprimée (par exemple, les vues référençant la colonne).

RESTRICT

Refuse de supprimer la colonne ou la contrainte si des objets en dépendent. Ceci est le comportement par défaut.

nomindex

Nom de l'index sur lequel la table doit être réorganisée en cluster.

nouveau_propriétaire

Le nom du nouveau propriétaire de la table.

nom_espacelogique

Le nom du tablespace où sera déplacé la table.

Notes

Le mot clé COLUMN n'est pas nécessaire. Il peut être omis.

Quand une colonne est ajoutée avec ADD COLUMN, toutes les lignes existantes de cette table sont initialisées avec la valeur par défaut de la colonne (NULL si aucune clause DEFAULT n'a été définie).

Ajouter une colonne avec une valeur par défaut différente de NULL ou modifier le type d'une colonne existante requiert que la table entière soit ré-écrite. Ceci pourrait prendre un temps considérable pour une grande table ; et cela demandera temporairement le double d'espace disque.

Ajouter une contrainte CHECK ou NOT NULL requiert de parcourir la table pour vérifier que les lignes existantes respectent cette contrainte.

La raison principale pour fournir l'option de spécification de changements multiples en une seule commande ALTER TABLE est que les parcours ou ré-écritures multiples de table peuvent être combinés en une seule passe sur la table.

La forme DROP COLUMN ne supprime pas physiquement la colonne, mais la rend simplement invisible au SQL. Par la suite, les ordres d'insertion et de mise à jour sur cette table stockeront une valeur NULL pour la colonne. Du coup, supprimer une colonne ne réduit pas immédiatement la taille de la table sur le disque car l'espace occupé par la colonne n'est pas récupéré. Cet espace sera récupéré petit à petit, au fur et à mesure des mises à jour des lignes de la table.

Le fait qu'ALTER TYPE requiert la ré-écriture de la table entière est quelque fois un avantage car le processus de ré-écriture élimine tout espace mort dans la table. Par exemple, pour réclamer immédiatement la place occupée par une colonne supprimée, la façon la plus rapide est

ALTER TABLE table ALTER COLUMN toutecolonne TYPE touttype;

toutecolonne est toute colonne de table restante et touttype est le même type que ce que possède déjà la colonne. Cela résulte en des modifications sémantiquement visibles dans la table mais la commande force la ré-écriture, qui oublie toute donnée inutile.

L'option USING d'ALTER TYPE peut en fait spécifier toute expression impliquant les anciennes valeurs de la ligne ; c'est-à-dire qu'il peut référencer les autres colonnes ainsi que celle en cours de conversion. Ceci permet des conversions très générales grâce à la syntaxe ALTER TYPE. À cause de cette flexibilité, l'expression USING n'est pas appliquée à la valeur par défaut de la colonne (si elle en a) ; le résultat pourrait ne pas être une expression constante requise pour une valeur par défaut. Cela signifie que, quand il n'existe pas de conversion implicite ou d'affectation de l'ancien au nouveau type, ALTER TYPE pourrait échouer dans sa conversion de la valeur par défaut bien que la clause USING soit spécifiée. Dans de tels cas, supprimez la valeur par défaut avec DROP DEFAULT, exécutez le ALTER TYPE et enfin utilisez SET DEFAULT pour ajouter une nouvelle valeur par défaut convenable. Des considérations similaires s'appliquent aux index et contraintes impliquant la colonne.

Si une table a des tables descendantes, il n'est pas possible d'ajouter, de renommer ou de modifier le type d'une colonne dans la table parent sans le faire aussi pour ses descendantes. Donc, la commande ALTER TABLE ONLY est rejetée. Ceci assure que les descendantes ont toujours des colonnes correspondant à celles de la table parente.

Un appel récursif à DROP COLUMN supprimera une colonne d'une table descendante si et seulement si la table descendante n'hérite pas de cette colonne d'une autre table et n'a jamais eu de définition indépendante de la colonne. Une suppression de colonne non récursive (c'est à dire une commande ALTER TABLE ONLY ... DROP COLUMN) ne supprime jamais les colonnes descendantes mais les marque comme définies de manière indépendante, plutôt qu'héritées.

On ne peut pas changer quoi que ce soit dans une table du catalogue système.

Voir la commande CREATE TABLE pour avoir une description plus complète des paramètres valides. Chapitre 5 donne plus d'informations sur l'héritage.

Exemples

Pour ajouter une colonne de type varchar à une table :

ALTER TABLE distributeurs ADD COLUMN adresse varchar(30);

Pour supprimer une colonne d'une table :

ALTER TABLE distributeurs DROP COLUMN adresse RESTRICT;

Pour modifier les types de deux colonnes existantes en une opération :

ALTER TABLE distributeurs
    ALTER COLUMN adresse TYPE varchar(80),
    ALTER COLUMN nom TYPE varchar(100);

Pour modifier une colonne de type entier contenant une date/heure UNIX en timestamp with time zone avec une clause USING :

ALTER TABLE foo
    ALTER COLUMN foo_timestamp TYPE timestamp with time zone
    USING
        timestamp with time zone 'epoch' + foo_timestamp * interval '1 second';

Pour renommer une colonne existante :

ALTER TABLE distributeurs RENAME COLUMN adresse TO city;

Pour renommer une table existante :

ALTER TABLE distributeurs RENAME TO suppliers;

Pour ajouter une contrainte NOT NULL à une colonne :

ALTER TABLE distributeurs ALTER COLUMN rue SET NOT NULL;

Pour supprimer une contrainte NOT NULL d'une colonne :

ALTER TABLE distributeurs ALTER COLUMN rue DROP NOT NULL;

Pour ajouter une contrainte de vérification sur une table :

ALTER TABLE distributeurs ADD CONSTRAINT verif_zip CHECK (char_length(zipcode) = 5);

Pour supprimer une contrainte de vérification d'une table et de toutes ses tables filles :

ALTER TABLE distributeurs DROP CONSTRAINT verif_zip;

Pour ajouter une contrainte de clé étrangère à une table :

ALTER TABLE distributeurs ADD CONSTRAINT distfk FOREIGN KEY (adresse) REFERENCES adresses (adresse) MATCH FULL;

Pour ajouter une contrainte unique (multicolonnes) à une table :

ALTER TABLE distributeurs ADD CONSTRAINT dist_id_zipcode_key UNIQUE (dist_id, zipcode);

Pour ajouter une clé primaire nommée automatiquement à une table. Remarque : une table ne peut avoir qu'une seule clé primaire dans toute sa vie.

ALTER TABLE distributeurs ADD PRIMARY KEY (dist_id);

Pour déplacer une table dans un tablespace différent :

ALTER TABLE distributeurs SET TABLESPACE espacelogiquerapide;

Compatibilité

Les formes ADD, DROP et SET DEFAULT se conforment au standard SQL. Les autres formes sont des extensions PostgreSQL au standard SQL. De plus, la capacité à spécifier plus d'une manipulation en une seule commande ALTER TABLE est une extension.

ALTER TABLE DROP COLUMN peut être utilisé pour supprimer la seule colonne d'une table, laissant une table sans colonne. C'est une extension de SQL, qui ne permet pas les tables sans colonne.