Deklarowanie domyślnego ograniczenia podczas tworzenia tabeli

100

Tworzę nową tabelę w Microsoft SQL Server 2000 pisząc kod zamiast korzystać z GUI, staram się nauczyć, jak to zrobić „ręcznie”.

To jest kod, którego faktycznie używam i działa dobrze:

CREATE TABLE "attachments"
(
    "attachment_id" INT NOT NULL,
    "load_date" SMALLDATETIME NOT NULL,
    "user" VARCHAR(25) NOT NULL,
    "file_name" VARCHAR(50) NOT NULL,
    CONSTRAINT "pk_attachments" PRIMARY KEY ("attachment_id"),
    CONSTRAINT "fk_users" FOREIGN KEY ("user") REFERENCES "users" ("user"),
    CONSTRAINT "ch_load_date" CHECK ("load_date" < GETDATE())
)

Podałem klucz podstawowy, klucz obcy i ograniczenia sprawdzające samodzielnie, ponieważ w ten sposób mogę zdefiniować dla nich nazwę, w przeciwnym razie zadeklarowanie ich w linii spowodowałoby, że SQL Server wygenerowałby losową nazwę, a mi się to nie "podoba".

Problem pojawił się, gdy próbowałem zadeklarować domyślne ograniczenie wartości: patrząc na informacje w Internecie i sposób ich tworzenia przez Microsoft SLQ Server Management Studio zrozumiałem, że można je tworzyć zarówno inline, jak i samodzielnie:

"load_date" SMALLDATETIME NOT NULL DEFAULT GETDATE()

lub

CONSTRAINT "df_load_date" DEFAULT GETDATE() FOR "load_date"

Metoda inline działa dobrze, ale jak zwykle generuje losową nazwę dla constaint, metoda samodzielna generuje błąd, mówiąc Incorrect syntax near 'FOR'..

Ponadto, jeśli utworzę tabelę, a następnie ALTERją, polecenie działa:

ALTER TABLE "attachments"
ADD CONSTRAINT "df_load_date" DEFAULT GETDATE() FOR "load_date"


Jako odniesienie, oto pełny kod, który próbuję wykonać:

CREATE TABLE "attachments"
(
    "attachment_id" INT NOT NULL,
    "load_date" SMALLDATETIME NOT NULL,
    "user" VARCHAR(25) NOT NULL,
    "file_name" VARCHAR(50) NOT NULL,
    CONSTRAINT "pk_attachments" PRIMARY KEY ("attachment_id"),
    CONSTRAINT "fk_users" FOREIGN KEY ("user") REFERENCES "users" ("user"),
    CONSTRAINT "ch_load_date" CHECK ("load_date" < GETDATE()),
    CONSTRAINT "df_load_date" DEFAULT GETDATE() FOR "load_date"
)



Jestem tu całkowicie zagubiony, czy to, czego staram się nie zrobić, jest niemożliwe, czy też robię coś źle?


Edytować:

David M pokazał, jak dodać nazwane domyślne ograniczenie za pomocą składni wbudowanej. Nadal staram się zrozumieć, czy samodzielna składnia jest całkowicie błędna, czy też jest to moja wina.

Albireo
źródło
3
Zgadzam się z edycją. Odpowiedź Davida M nie obejmuje sposobu dodawania ograniczenia za pomocą samodzielnej deklaracji ograniczenia, ale ponieważ BOL nie ma żadnych przykładów, w których można nazwać domyślne ograniczenie, z wyjątkiem sposobu, w jaki pokazał David M, myślę, że można bezpiecznie założyć SQL Serwer (niespójnie) nie obsługuje tej składni.
Peter Majeed,

Odpowiedzi:

177

Zrób to w linii z tworzeniem kolumny:

[load_date] SMALLDATETIME NOT NULL
        CONSTRAINT [df_load_date] DEFAULT GETDATE()

Użyłem nawiasów kwadratowych zamiast cudzysłowów, ponieważ wielu czytelników nie będzie QUOTED_IDENTIFIERSdomyślnie działać .

David M
źródło
3
Dzięki, to rozwiązuje problem z nazwą. Teraz próbuję dowiedzieć się, czy to zachowanie jest „zgodne z projektem” (tj. Nie można tego zrobić), czy też jest na to sposób. Wiesz, lubię utrzymywać mój kod w porządku, a deklarowanie ograniczeń po kolumnach sprawia, że ​​pliki SQL są bardziej przejrzyste i łatwiejsze do zrozumienia i debugowania (a przynajmniej tak mi się wydaje).
Albireo
3
@Albireo - zgodnie z projektem. table_constraintw gramatyce nie obejmujeDEFAULT
Martin Smith
2
To rozwiązanie działa u mnie tylko wtedy, gdy usuwam cudzysłowy wokół pól i nazw ograniczeń.
David S.
1
W przypadku nowszych wersji programu SQL Server użyj [load_date] SMALLDATETIME NOT NULL CONSTRAINT [df_load_date] DEFAULT GETDATE(). Zwróć uwagę na nawiasy kwadratowe zamiast podwójnych cudzysłowów.
śmiertelny pies
3
Właściwie nie jest to nowsza / starsza wersja - SET QUOTED_IDENTIFIERprzełącza. Zrewiduję odpowiedź, ponieważ i tak wolę nawiasy kwadratowe, właśnie podążyłem za stylem pytania OP.
David M