Puis-je créer une contrainte nommée par défaut dans une instruction d'ajout de colonne dans SQL Server?

163

Dans SQL Server, j'ai une nouvelle colonne sur une table:

ALTER TABLE t_tableName 
    ADD newColumn NOT NULL

Cela échoue car je spécifie NOT NULL sans spécifier de contrainte par défaut. La table ne doit pas avoir de contrainte par défaut.

Pour contourner cela, je pourrais créer la table avec la contrainte par défaut, puis la supprimer.

Cependant, il ne semble pas y avoir de moyen de spécifier que la contrainte par défaut doit être nommée dans le cadre de cette instruction, donc ma seule façon de m'en débarrasser est d'avoir une procédure stockée qui la recherche dans le sys.default_constraints table.

C'est un peu compliqué / verbeux pour une opération qui est susceptible de se produire souvent. Quelqu'un a-t-il de meilleures solutions pour cela?

GlennS
la source

Réponses:

224

Cela devrait fonctionner:

ALTER TABLE t_tableName 
    ADD newColumn VARCHAR(50)
    CONSTRAINT YourContraintName DEFAULT '' NOT NULL
Joe Stefanelli
la source
1
Fonctionne aussi en 2012. Détails Gory: msdn.microsoft.com/en-us/library/ms187742.aspx
adam77
10
Pourquoi ne pas mettre le NOT NULLadjacent au type de données? Il peut être syntaxiquement valide de le mettre après la contrainte, mais il semble déroutant de le mettre là.
Tullo_x86
102
ALTER TABLE t_tableName 
    ADD newColumn int NOT NULL
        CONSTRAINT DF_defaultvalue DEFAULT (1)
Blé Mitch
la source
22
Je préfère cela à la réponse acceptée car je peux supprimer la contrainte par défaut sans craindre de perdre la contrainte NOT NULL.
EleventhDoctor
7
@EleventhDoctor Cela n'a aucun sens. Le NOT NULL ne fait pas partie de la contrainte et l'instruction drop fait simplement référence au nom de la contrainte
Roger Willcocks
11
@RogerWillcocks Vous avez raison, mais il est plus clair à la lecture que NOT NULL est séparé de la contrainte.
deluxxxe
10

Je voudrais ajouter quelques détails, car les réponses existantes sont plutôt minces :

L'astuce la plus importante est la suivante: vous ne devriez jamais créer une contrainte sans nom explicite!

Le plus gros problème avec les contraintes sans nom : lorsque vous exécutez cela sur différentes machines client, vous obtiendrez des noms différents / aléatoires sur chacun.
Tout futur script de mise à niveau sera un véritable casse-tête ...

Le conseil général est:

  • Pas de contrainte sans nom!
  • Utilisez une convention de dénomination, par exemple
    • DF_TableName_ColumnName pour une contrainte par défaut
    • CK_TableName_ColumnName pour une contrainte de contrôle
    • UQ_TableName_ColumnName pour une contrainte unique
    • PK_TableName pour une contrainte de clé primaire

La syntaxe générale est

TheColumn <DataType> Nullability CONSTRAINT ConstraintName <ConstraintType> <ConstraintDetails>

Essayez ceci ici

Vous pouvez ajouter plus de contraintes à chaque colonne et vous pouvez ajouter des contraintes supplémentaires tout comme vous ajoutez des colonnes après une virgule:

CREATE TABLE dbo.SomeOtherTable(TheIdThere INT NOT NULL CONSTRAINT PK_SomeOtherTable PRIMARY KEY)
GO
CREATE TABLE dbo.TestTable
(
 --define the primary key
 ID INT IDENTITY NOT NULL CONSTRAINT PK_TestTable PRIMARY KEY

 --let the string be unique (results in a unique index implicitly)
,SomeUniqueString VARCHAR(100) NOT NULL CONSTRAINT UQ_TestTable_SomeUniqueString UNIQUE

 --define two constraints, one for a default value and one for a value check
,SomeNumber INT NULL CONSTRAINT DF_TestTable_SomeNumber DEFAULT (0)
                     CONSTRAINT CK_TestTable_SomeNumber_gt100 CHECK(SomeNumber>100)

 --add a foreign key constraint
,SomeFK INT NOT NULL CONSTRAINT FK_TestTable_SomeFK FOREIGN KEY REFERENCES dbo.SomeOtherTable(TheIdThere)

 --add a constraint for two columns separately
,CONSTRAINT UQ_TestTable_StringAndNumber UNIQUE(SomeFK,SomeNumber)
);
GO

--insérez des données

INSERT INTO dbo.SomeOtherTable VALUES(1);
INSERT INTO dbo.TestTable(SomeUniqueString,SomeNumber,SomeFK) VALUES('hello',111,1);
GO
INSERT INTO dbo.TestTable(SomeUniqueString,SomeNumber,SomeFK) 
VALUES('fails due to uniqueness of 111,1',111,1);
Shnugo
la source
1

Essayez comme ci-dessous le script-

ALTER TABLE DEMO_TABLE
ADD Column1 INT CONSTRAINT Def_Column1 DEFAULT(3) NOT NULL,
    Column2 VARCHAR(10) CONSTRAINT Def_Column2 DEFAULT('New') NOT NULL;
GO
Arulmouzhi
la source