Чи можу я створити іменоване обмеження за замовчуванням в операторі додавання стовпця в 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 році. Деталі Gory: 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 не є частиною обмеження, і у заяві про падіння просто згадується назва обмеження
Roger Willcocks

11
@RogerWillcocks Ви маєте рацію, але прочитавши її зрозуміліше, що NOT NULL є окремим від обмеження.
deluxxxe

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.