Declarar una restricción predeterminada al crear una tabla

100

Estoy creando una nueva tabla en Microsoft SQL Server 2000 escribiendo el código en lugar de usar la GUI, estoy tratando de aprender cómo hacerlo "de forma manual".

Este es el código que estoy usando y funciona 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())
)

He especificado la clave principal, la clave externa y las restricciones de verificación por su cuenta porque de esta manera puedo definir un nombre para ellas, de lo contrario, declararlas en línea haría que SQL Server generara un nombre aleatorio, y no me "gusta".

El problema surgió cuando traté de declarar la restricción de valor predeterminado: mirando la información en Internet y cómo la crea Microsoft SLQ Server Management Studio, entendí que se puede crear tanto en línea como por sí solo:

"load_date" SMALLDATETIME NOT NULL DEFAULT GETDATE()

o

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

El método en línea funciona bien, pero genera como de costumbre un nombre aleatorio para la constancia, el método independiente arroja un error, diciendo Incorrect syntax near 'FOR'..

Además, si creo la tabla y luego ALTER, el comando funciona:

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


Como referencia, aquí está el código completo que estoy tratando de ejecutar:

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



Estoy totalmente perdido aquí, ¿lo que estoy tratando de hacer es imposible o estoy haciendo algo mal?


Editar:

David M mostró cómo agregar una restricción predeterminada con nombre usando la sintaxis en línea, todavía estoy buscando comprender si la sintaxis independiente es completamente incorrecta o es mi culpa.

Albireo
fuente
3
Estoy de acuerdo con la edición. La respuesta de David M no cubre cómo agregar una restricción a través de una declaración de restricción independiente, pero dado que BOL no tiene ningún ejemplo en el que pueda nombrar la restricción predeterminada, excepto a través de la forma en que David M demostró, creo que es seguro asumir SQL El servidor (de manera inconsistente) no admite esta sintaxis.
Peter Majeed

Respuestas:

177

Hágalo en línea con la creación de la columna:

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

He utilizado corchetes en lugar de comillas, ya que muchos lectores no trabajarán con ellos QUOTED_IDENTIFIERSde forma predeterminada.

David M
fuente
3
Gracias, eso resuelve el problema del nombre. Ahora estoy tratando de averiguar si este comportamiento es "por diseño" (es decir, no es posible hacerlo) o si hay una manera de hacerlo. Sabes, me gusta mantener mi código "ordenado" y tener las restricciones declaradas después de las columnas hace que los archivos SQL sean más claros y fáciles de entender y depurar (o al menos eso es lo que creo).
Albireo
3
@Albireo - Por diseño. table_constrainten la gramática no incluyeDEFAULT
Martin Smith
2
Esta solución solo funciona para mí cuando elimino las comillas alrededor del campo y los nombres de las restricciones.
David S.
1
Para versiones más recientes de SQL Server, use [load_date] SMALLDATETIME NOT NULL CONSTRAINT [df_load_date] DEFAULT GETDATE(). Observe los corchetes en lugar de las comillas dobles.
deadlydog
3
En realidad, no es una versión más nueva / anterior: SET QUOTED_IDENTIFIERalterna. Revisaré la respuesta, ya que prefiero los corchetes de todos modos, acabo de seguir el estilo de la pregunta del OP.
David M