Déclaration d'une contrainte par défaut lors de la création d'une table

100

Je crée une nouvelle table dans Microsoft SQL Server 2000 en écrivant le code au lieu d'utiliser l'interface graphique, j'essaie d'apprendre à le faire "à la manière manuelle".

C'est le code que j'utilise actuellement, et cela fonctionne bien:

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

J'ai spécifié la clé primaire, la clé étrangère et les contraintes de vérification de leur propre chef parce que de cette façon je peux définir un nom pour eux, sinon les déclarer en ligne ferait de SQL Server générer un nom aléatoire, et je ne "aime" pas.

Le problème est survenu lorsque j'ai essayé de déclarer la contrainte de valeur par défaut: en regardant les informations sur Internet et comment Microsoft SLQ Server Management Studio le crée, j'ai compris qu'il pouvait être créé à la fois en ligne et seul:

"load_date" SMALLDATETIME NOT NULL DEFAULT GETDATE()

ou

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

La méthode en ligne fonctionne bien, mais elle génère comme d'habitude un nom aléatoire pour la contrainte, la méthode autonome lève une erreur, en disant Incorrect syntax near 'FOR'..

De plus, si je crée la table puis que je la crée ALTER, la commande fonctionne:

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


À titre de référence, voici le code complet que j'essaie d'exécuter:

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



Je suis totalement perdu ici, est-ce que ce que j'essaie de faire n'est pas possible, ou je fais quelque chose de mal?


Éditer:

David M a montré comment ajouter une contrainte nommée par défaut à l'aide de la syntaxe en ligne, je cherche toujours à comprendre si la syntaxe autonome est complètement fausse ou si c'est de ma faute.

Albireo
la source
3
Je suis d'accord avec la modification. La réponse de David M ne couvre pas comment ajouter une contrainte via une déclaration de contrainte autonome, mais comme BOL n'a pas d'exemples où vous pouvez nommer la contrainte par défaut sauf via la façon dont David M l'a démontré, je pense qu'il est prudent de supposer SQL Le serveur (de manière incohérente) ne prend pas en charge cette syntaxe.
Peter Majeed

Réponses:

177

Faites-le en ligne avec la création de la colonne:

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

J'ai utilisé des crochets plutôt que des guillemets, car de nombreux lecteurs ne travailleront pas avec QUOTED_IDENTIFIERSpar défaut.

David M
la source
3
Merci, cela résout le problème de nom. J'essaie maintenant de comprendre si ce comportement est «par conception» (c'est-à-dire qu'il n'est pas possible de le faire) ou s'il existe un moyen de le faire. Vous savez, j'aime garder mon code «rangé» et avoir les contraintes déclarées après les colonnes rend les fichiers SQL plus clairs et plus faciles à comprendre et à déboguer (ou du moins c'est ce que je pense).
Albireo
3
@Albireo - Par conception. table_constraintdans la grammaire ne comprend pasDEFAULT
Martin Smith
2
Cette solution ne fonctionne pour moi que lorsque je supprime les guillemets autour des noms de champ et de contrainte.
David S.
1
Pour les versions plus récentes de SQL Server, utilisez [load_date] SMALLDATETIME NOT NULL CONSTRAINT [df_load_date] DEFAULT GETDATE(). Notez les crochets au lieu des guillemets doubles.
deadlydog
3
Pas vraiment une chose de version plus récente / plus ancienne - SET QUOTED_IDENTIFIERbascule. Je réviserai la réponse, comme je préfère de toute façon les crochets, je venais de suivre le style de la question du PO.
David M