Czy mogę utworzyć nazwane domyślne ograniczenie w instrukcji dodawania kolumny w programie SQL Server?


163

W SQL Server mam nową kolumnę w tabeli:

ALTER TABLE t_tableName 
    ADD newColumn NOT NULL

Nie udaje się to, ponieważ określam NIE NULL bez określenia domyślnego ograniczenia. Tabela nie powinna mieć domyślnego ograniczenia.

Aby obejść ten problem, mógłbym utworzyć tabelę z domyślnym ograniczeniem, a następnie ją usunąć.

Jednak wydaje się, że nie ma sposobu, aby określić, że domyślne ograniczenie powinno być nazwane jako część tej instrukcji, więc moim jedynym sposobem na pozbycie się go jest posiadanie procedury składowanej, która wyszukuje ją w sys.default_constraints stół.

Jest to trochę niechlujne / rozwlekłe w przypadku operacji, która może się często zdarzać. Czy ktoś ma na to lepsze rozwiązania?

Odpowiedzi:


224

To powinno działać:

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

1
Działa również w 2012 roku. Gory details: msdn.microsoft.com/en-us/library/ms187742.aspx
adam77

10
Dlaczego nie umieścić NOT NULLobok typu danych? Umieszczenie go po ograniczeniu może być poprawne pod względem składniowym, ale umieszczenie go w tym miejscu wydaje się być mylące.
Tullo_x86

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

22
Wolę to od zaakceptowanej odpowiedzi, ponieważ mogę porzucić domyślne ograniczenie bez obawy o utratę ograniczenia NOT NULL.
Jedenasty

7
@EleventhDoctor To nie ma sensu. NOT NULL nie jest częścią ograniczenia, a instrukcja drop odwołuje się tylko do nazwy ograniczenia
Roger Willcocks

11
@RogerWillcocks Masz rację, ale po przeczytaniu staje się jaśniejsze, że NOT NULL jest oddzielone od ograniczenia.
deluxxxe

10

Chciałbym dodać kilka szczegółów, ponieważ istniejące odpowiedzi są raczej cienkie :

Najważniejsza wskazówka to: Nigdy, przenigdy nie powinieneś tworzyć ograniczenia bez wyraźnej nazwy!

Największy problem z nienazwanymi ograniczeniami : kiedy wykonujesz to na różnych komputerach klientów, otrzymasz różne / losowe nazwy na każdym z nich.
Każdy przyszły skrypt aktualizacji będzie prawdziwym bólem głowy ...

Ogólna rada to:

  • Żadnych ograniczeń bez nazwy!
  • Użyj pewnej konwencji nazewnictwa, np
    • DF_TableName_ColumnName dla domyślnego ograniczenia
    • CK_TableName_ColumnName dla ograniczenia sprawdzającego
    • UQ_TableName_ColumnName dla unikalnego ograniczenia
    • PK_TableName dla ograniczenia klucza podstawowego

Ogólna składnia to

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

Spróbuj tego tutaj

Możesz dodać więcej ograniczeń do każdej kolumny i możesz dodać dodatkowe ograniczenia, tak jak dodajesz kolumny po przecinku:

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

- wstaw jakieś dane

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

Spróbuj jak poniżej skrypt-

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.