Considérez le tableau suivant avec environ 10 millions de lignes
CREATE TABLE user
(
id bigint NOT NULL,
...
CONSTRAINT user_pk PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
)
Ensuite, j'ai appliqué l'alter suivant
ALTER TABLE USER ADD COLUMN BUSINESS_ID VARCHAR2(50);
--OK
UPDATE USER SET BUSINESS_ID = ID; //~1500 sec
--OK
ALTER TABLE USER ALTER COLUMN BUSINESS_ID SET NOT NULL;
ERROR: column "business_id" contains null values
SQL state: 23502
C'est très étrange car la colonne id (qui a été copiée dans la colonne business_id) ne peut pas contenir de valeurs nulles car c'est la clé primaire, mais pour être sûr de la vérifier
select count(*) from USER where BUSINESS_ID is null
--0 records
Je soupçonne que c'est un bug, je me demande juste si je manque quelque chose de trivial
La seule explication logique serait un simultané INSERT
..
(Utilisation de tbl
au lieu du mot réservé user
comme nom de table.)
ALTER TABLE tbl ADD COLUMN BUSINESS_ID VARCHAR2(50);
--OK
UPDATE tbl SET BUSINESS_ID = ID; //~1500 sec
--OK
HERE
ALTER TABLE tbl ALTER COLUMN BUSINESS_ID SET NOT NULL;
Pour éviter cela, utilisez plutôt:
ALTER TABLE tbl
ADD COLUMN BUSINESS_ID VARCHAR(50) DEFAULT ''; -- or whatever is appropriate
...
Ensuite, vous pouvez vous retrouver avec une valeur par défaut dans certaines lignes. Vous voudrez peut-être vérifier.
Ou exécutez tout comme bloc de transaction et prenez un verrou exclusif pour être sûr:
BEGIN;
LOCK tbl;
ALTER ...
UPDATE ...
ALTER ...
COMMIT;
Peut-être qu'il veut une valeur par défaut? Documents Postgresql sur ALTER :
Pour ajouter une colonne, utilisez une commande comme celle-ci:
ALTER TABLE products ADD COLUMN description text;
La nouvelle colonne est initialement remplie avec la valeur par défaut donnée ( null si vous ne spécifiez pas de clause DEFAULT ).
Alors,
ALTER TABLE USER ALTER COLUMN BUSINESS_ID SET DEFAULT="",
ALTER COLUMN BUSINESS_ID SET NOT NULL;
Vous ne pouvez pas faire cela lors de la même transaction. Ajoutez votre colonne et mettez-la à jour. Ensuite, dans une transaction distincte, définissez la contrainte non nulle.