Declaração de uma restrição padrão ao criar uma tabela

100

Estou criando uma nova tabela no Microsoft SQL server 2000 escrevendo o código em vez de usar a GUI, estou tentando aprender como fazê-lo "do modo manual".

Este é o código que estou realmente usando e funciona bem:

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

Especifiquei a chave primária, a chave estrangeira e as restrições de verificação por conta própria porque, dessa forma, posso definir um nome para elas, caso contrário, declará-las inline faria o SQL Server gerar um nome aleatório, e eu não "gosto" disso.

O problema surgiu quando tentei declarar a restrição de valor padrão: olhando as informações na internet e como o Microsoft SLQ Server Management Studio as cria, entendi que pode ser criado tanto inline quanto por conta própria:

"load_date" SMALLDATETIME NOT NULL DEFAULT GETDATE()

ou

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

O método inline funciona bem, mas gera, como sempre, um nome aleatório para a constaint, o método autônomo gera um erro, dizendo Incorrect syntax near 'FOR'..

Além disso, se eu criar a tabela e depois ALTERela, o comando funcionará:

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


Como referência, aqui está o código completo que estou tentando executar:

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



Estou totalmente perdido aqui, o que estou tentando fazer não é possível ou estou fazendo algo errado?


Editar:

David M mostrou como adicionar uma restrição padrão nomeada usando a sintaxe embutida, ainda estou procurando entender se a sintaxe autônoma está completamente errada ou é minha culpa.

Albireo
fonte
3
Eu concordo com a edição. A resposta de David M não cobre como adicionar uma restrição por meio de uma declaração de restrição autônoma, mas como o BOL não tem nenhum exemplo onde você possa nomear a restrição padrão, exceto pela forma como David M demonstrou, acho que é seguro assumir SQL O servidor (inconsistentemente) não oferece suporte a esta sintaxe.
Peter Majeed

Respostas:

177

Faça isso em linha com a criação da coluna:

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

Usei colchetes em vez de citações, pois muitos leitores não funcionam QUOTED_IDENTIFIERSpor padrão.

David M
fonte
3
Obrigado, isso resolve o problema do nome. Agora estou tentando descobrir se esse comportamento é "intencional" (ou seja, não é possível fazê-lo) ou se há uma maneira de fazê-lo. Você sabe, eu gosto de manter meu código "organizado" e ter as restrições declaradas após as colunas torna os arquivos SQL mais claros e fáceis de entender e depurar (ou pelo menos é o que eu acho).
Albireo
3
@Albireo - Por design. table_constraintna gramática não incluiDEFAULT
Martin Smith
2
Esta solução só funciona para mim quando removo as aspas em torno dos nomes de campo e restrição.
David S.
1
Para versões mais recentes do SQL Server, use [load_date] SMALLDATETIME NOT NULL CONSTRAINT [df_load_date] DEFAULT GETDATE(). Observe os colchetes em vez das aspas duplas.
deadlydog
3
Não é realmente uma coisa de versão mais nova / mais antiga - SET QUOTED_IDENTIFIERalterna. Vou revisar a resposta, pois prefiro os colchetes de qualquer maneira, pois acabava de seguir o estilo da pergunta do OP.
David M de