338 votes

Comment puis-je ajouter une colonne qui n'autorise pas les valeurs nulles dans une base de données Postgresql ?

J'ajoute une nouvelle colonne "NOT NULL" à ma base de données Postgresql en utilisant la requête suivante (aseptisée pour l'Internet) :

ALTER TABLE mytable ADD COLUMN mycolumn character varying(50) NOT NULL;

Chaque fois que j'exécute cette requête, je reçois le message d'erreur suivant :

ERROR:  column "mycolumn" contains null values

Je suis perplexe. Où est-ce que je me trompe ?

REMARQUE : j'utilise principalement pgAdmin III (1.8.4), mais j'ai reçu la même erreur lorsque j'ai exécuté le SQL à partir de Terminal.

519voto

Luc M Points 4950

Vous devez définir une valeur par défaut.

ALTER TABLE mytable ADD COLUMN mycolumn character varying(50) NOT NULL DEFAULT 'foo';

... some work (set real values as you want)...

ALTER TABLE mytable ALTER COLUMN mycolumn DROP DEFAULT;

7 votes

@SeanBright , vous pouvez accéder à la doc postgres hors ligne en faisant man ALTER_TABLE :)

4 votes

Pour clarifier : la valeur par défaut n'est nécessaire que pour mettre à jour les lignes existantes, c'est pourquoi elle peut être abandonnée immédiatement après. Toutes les lignes existantes ont été mises à jour lorsque la table a été modifiée (ce qui peut prendre un certain temps, évidemment).

4 votes

Cela ne fonctionnera pas si vous souhaitez utiliser une autre colonne pour calculer la valeur initiale des lignes existantes. Réponse de j_random_hacker permet de le faire, ce qui le rend plus robuste.

125voto

j_random_hacker Points 28473

Comme d'autres l'ont fait remarquer, vous devez soit créer une colonne annulable, soit fournir une valeur par défaut. Si cela n'est pas assez flexible (par exemple si vous avez besoin que la nouvelle valeur soit calculée pour chaque ligne individuellement), vous pouvez utiliser le fait que dans PostgreSQL, toutes les commandes DDL peuvent être exécutées dans une transaction :

BEGIN;
ALTER TABLE mytable ADD COLUMN mycolumn character varying(50);
UPDATE mytable SET mycolumn = timeofday();    -- Just a silly example
ALTER TABLE mytable ALTER COLUMN mycolumn SET NOT NULL;
COMMIT;

13 votes

Même dans une transaction, NOT NULL est appliqué immédiatement, donc il faut d'abord ajouter une colonne, remplir les valeurs, puis ajouter NOT NULL - comme le fait cette réponse. (testé sur postgres 9.6)

55voto

Sean Bright Points 39480

Étant donné que des lignes existent déjà dans la table, la fonction ALTER essaie d'insérer NULL dans la colonne nouvellement créée pour toutes les lignes existantes. Vous devriez ajouter la colonne en permettant NULL puis remplissez la colonne avec les valeurs que vous voulez, et ensuite mettez-le sur NOT NULL après.

14 votes

Un exemple de la manière de le faire aurait été vraiment bien. Sinon, la solution de Luc semble plus complète et prête à l'emploi.

6voto

Paul Tomblin Points 83687

Vous devez soit définir une valeur par défaut, soit faire ce que dit Sean et l'ajouter sans la contrainte nulle jusqu'à ce que vous l'ayez remplie sur les lignes existantes.

3voto

Ryan Graham Points 4734

La spécification d'une valeur par défaut fonctionnerait également, en supposant qu'une valeur par défaut soit appropriée.

5 votes

Cela améliorerait la réponse de donner la syntaxe modifiée pour créer la colonne avec une valeur par défaut (à titre d'illustration).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X