Можно ли создать именованное ограничение по умолчанию в операторе добавления столбца в SQL Server?


163

В SQL Server у меня есть новый столбец в таблице:

ALTER TABLE t_tableName 
    ADD newColumn NOT NULL

Это терпит неудачу, потому что я указываю NOT NULL без указания ограничения по умолчанию. Таблица не должна иметь ограничения по умолчанию.

Чтобы обойти это, я мог бы создать таблицу с ограничением по умолчанию, а затем удалить ее.

Однако, похоже, нет никакого способа указать, что ограничение по умолчанию должно быть названо как часть этого оператора, поэтому мой единственный способ избавиться от него - это иметь хранимую процедуру, которая ищет его в sys.default_constraints. стол.

Это немного грязно / многословно для операции, которая может случиться много. У кого-нибудь есть лучшие решения для этого?

Ответы:


224

Это должно работать:

ALTER TABLE t_tableName 
    ADD newColumn VARCHAR(50)
    CONSTRAINT YourContraintName DEFAULT '' NOT NULL

1
Работает и в 2012 году. Детали Гори: msdn.microsoft.com/en-us/library/ms187742.aspx
adam77

10
Почему бы не поставить NOT NULLсмежный тип данных? Это может быть синтаксически допустимым, чтобы поместить его после ограничения, но это кажется запутанным, чтобы поместить его там.
Tullo_x86

102
ALTER TABLE t_tableName 
    ADD newColumn int NOT NULL
        CONSTRAINT DF_defaultvalue DEFAULT (1)

22
Я предпочитаю это принятому ответу, поскольку я могу удалить ограничение по умолчанию, не беспокоясь о потере ограничения NOT NULL.
Одиннадцатое

7
@EleventhDoctor Это не имеет смысла. NOT NULL не является частью ограничения, а оператор drop просто ссылается на имя ограничения
Roger Willcocks

11
@RogerWillcocks Вы правы, но после прочтения становится понятнее, что NOT NULL отделен от ограничения.
Делюкс

10

Я хотел бы добавить некоторые детали, поскольку существующие ответы довольно тонкие :

Самый важный совет: никогда не создавайте ограничение без явного имени!

Самая большая проблема с безымянными ограничениями : при выполнении этого на разных клиентских компьютерах вы получите разные / случайные имена на каждом.
Любой будущий скрипт обновления будет настоящей головной болью ...

Общий совет:

  • Нет ограничений без имени!
  • Используйте некоторые соглашения об именах, например
    • DF_TableName_ColumnName для ограничения по умолчанию
    • CK_TableName_ColumnName для проверки ограничения
    • UQ_TableName_ColumnName для уникального ограничения
    • PK_TableName для ограничения первичного ключа

Общий синтаксис

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

Попробуйте это здесь

Вы можете добавить больше ограничений для каждого столбца, а также добавить дополнительные ограничения так же, как добавляете столбцы после запятой:

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

- вставить некоторые данные

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);

1

Попробуйте как ниже скрипт

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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.