insérer une colonne NOT NULL dans une table existante


122

J'ai essayé:

ALTER TABLE MY_TABLE 
ADD STAGE INT NOT NULL;

Mais cela donne ce message d'erreur:

ALTER TABLE autorise uniquement l'ajout de colonnes pouvant contenir des valeurs nulles ou avoir une définition DEFAULT spécifiée

Réponses:


223

En option, vous pouvez initialement créer une colonne Null-able, puis mettre à jour votre colonne de table avec des valeurs non nulles valides et enfin ALTER column pour définir la contrainte NOT NULL:

ALTER TABLE MY_TABLE ADD STAGE INT NULL
GO
UPDATE MY_TABLE SET <a valid not null values for your column>
GO
ALTER TABLE MY_TABLE ALTER COLUMN STAGE INT NOT NULL
GO

Une autre option consiste à spécifier la valeur par défaut correcte pour votre colonne:

ALTER TABLE MY_TABLE ADD STAGE INT NOT NULL DEFAULT '0'

UPD: Veuillez noter que la réponse ci-dessus contient GOce qui est indispensable lorsque vous exécutez ce code sur un serveur Microsoft SQL. Si vous souhaitez effectuer la même opération sur Oracle ou MySQL, vous devez utiliser un point-virgule ;comme celui-ci:

ALTER TABLE MY_TABLE ADD STAGE INT NULL;
UPDATE MY_TABLE SET <a valid not null values for your column>;
ALTER TABLE MY_TABLE ALTER COLUMN STAGE INT NOT NULL;

1
Personnellement, je préfère le premier moyen ici si vous avez des valeurs que vous pouvez mettre manuellement sur le terrain. De cette façon, vous n'avez pas à vous soucier de la création et de la suppression d'une contrainte par défaut là où vous n'en avez pas besoin.
Mark W Dickson

1
@acarlon - Je pense que cela atteint. La updatedéclaration dangereuse que vous mentionnez serait préjudiciable dans toute requête. Cela devrait être assez simple pour voir si vous avez une colonne supplémentaire dans l' updateinstruction ici. Vous n'ajouteriez généralement qu'une ou deux colonnes à la fois. S'il vous arrive d'ajouter une colonne supplémentaire dans votre updatedéclaration qui n'y appartient pas, dans cet exemple, vous ne devriez peut-être pas être en charge des données en premier lieu.
Mark W Dickson

2
ANDROID Les développeurs utilisant SQLite doivent savoir que ce ALTER COLUMNn'est PAS pris en charge dans SQLite.
Sdghasemi

2
Je n'ai jamais vu GOauparavant et cela ne semble pas faire partie de la spécification SQL , donc cela entraînera probablement un échec pour les scripts non exécutés par l'un des outils qui le prennent en charge. Utilisez simplement des points-virgules? Je ne recommande pas de diffuser les normes Microsoft car ils se soucient rarement de toute norme établie et raisonnable, mais inventent les leurs juste pour se faire inventer eux-mêmes. En dehors de cela, réponse utile.
Neonit

2
@Neon merci pour le commentaire, mais la question originale concernait le serveur MS SQL, c'est pourquoi GO est là. Mais j'ajouterai une note à ce sujet à ma réponse.
Pavel Morshenyuk

13

Si vous n'autorisez pas la colonne à être Null, vous devez fournir une valeur par défaut pour remplir les lignes existantes. par exemple

ALTER TABLE dbo.YourTbl ADD
    newcol int NOT NULL CONSTRAINT DF_YourTbl_newcol DEFAULT 0

Sur Enterprise Edition, il s'agit d'un changement de métadonnées uniquement depuis 2012


2
Vous n'avez pas besoin de le faire, mais c'est une option.
Matt

6

Le message d'erreur est assez descriptif, essayez:

ALTER TABLE MyTable ADD Stage INT NOT NULL DEFAULT '-';

et quelle est la signification du "moins" dans la partie par défaut?
Mladen B.

3

D'autres implémentations SQL ont des restrictions similaires. La raison en est que l'ajout d'une colonne nécessite l'ajout de valeurs pour cette colonne (logiquement, même si ce n'est pas physiquement), qui par défaut sont NULL. Si vous n'autorisez pas NULLet n'avez pas de default, quelle sera la valeur?

Étant donné que SQL Server prend en charge ADD CONSTRAINT, je recommande l'approche de Pavel consistant à créer une colonne Nullable, puis à ajouter une NOT NULLcontrainte après l'avoir remplie avec des non- NULLvaleurs.


MySQL prend en charge l'ajout de colonnes non nulles dans une table existante avec des données, où la valeur vide "sensible" pour le type de données est fournie dans les lignes existantes (c'est-à-dire 0.0 pour float, 0 pour entier, chaîne vide pour chaîne, etc.).
Michael Tsang

2

Cela a fonctionné pour moi, peut également être "emprunté" à la vue de conception, apporter des modifications -> clic droit -> générer un script de modification.

BEGIN TRANSACTION
GO
ALTER TABLE dbo.YOURTABLE ADD
    YOURCOLUMN bit NOT NULL CONSTRAINT DF_YOURTABLE_YOURCOLUMN DEFAULT 0
GO
COMMIT

1
ALTER TABLE `MY_TABLE` ADD COLUMN `STAGE` INTEGER UNSIGNED NOT NULL AFTER `PREV_COLUMN`;

0
Alter TABLE 'TARGET' add 'ShouldAddColumn' Integer Not Null default "0"

1
Qu'est-ce que cette réponse ajoute à ce sujet?
barbsan
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.