创建表时声明默认约束

Posted

技术标签:

【中文标题】创建表时声明默认约束【英文标题】:Declaring a default constraint when creating a table 【发布时间】:2010-12-19 10:57:29 【问题描述】:

我正在通过编写代码而不是使用 GUI 在 Microsoft SQL Server 2000 中创建一个新表,我正在尝试学习如何“手动”进行操作。

这是我实际使用的代码,它运行良好:

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

我已经自己指定了主键、外键和检查约束,因为这样我可以为它们定义一个名称,否则将它们声明为内联会使 SQL Server 生成一个随机名称,我不“喜欢”它。

当我尝试声明默认值约束时出现了问题:查看互联网上的信息以及 Microsoft SLQ Server Management Studio 如何创建它,我了解到它可以内联和单独创建:

"load_date" SMALLDATETIME NOT NULL DEFAULT GETDATE()

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

内联方法工作正常,但它像往常一样为常量生成一个随机名称,独立方法抛出错误,说Incorrect syntax near 'FOR'.

另外,如果我创建表然后ALTER 它,该命令有效:

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

作为参考,这是我尝试执行的完整代码:

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

我在这里完全不知所措,是我试图做的事情是不可能的,还是我做错了什么?

编辑:

David M 展示了如何使用内联语法添加命名默认约束,我仍然希望了解独立语法是完全错误还是我的错。

【问题讨论】:

我同意编辑。 David M 的回复并未涵盖如何通过独立的约束声明添加约束,但由于 BOL 没有任何示例,您可以通过 David M 演示的方式将默认约束命名为 except,我认为假设 SQL Server(不一致)不支持这种语法是安全的。 另见:Incorrect syntax near 'for' SQL Server 【参考方案1】:

在创建列时内联:

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

我使用方括号而不是引号,因为默认情况下许多读者无法使用QUOTED_IDENTIFIERS

【讨论】:

谢谢,这解决了名称问题。现在我试图弄清楚这种行为是否是“设计使然”(即不可能做到)或者是否有办法做到这一点。你知道,我喜欢保持我的代码“整洁”,并且在列之后声明约束使 SQL 文件更清晰、更容易理解和调试(或者至少我是这么认为的)。 @Albireo - 设计。 table_constraint 中的 the grammar 不包括 DEFAULT 此解决方案仅在我删除字段和约束名称周围的引号时才适用。 对于较新版本的 SQL Server,请使用 [load_date] SMALLDATETIME NOT NULL CONSTRAINT [df_load_date] DEFAULT GETDATE()。注意方括号而不是双引号。 实际上不是更新/旧版本的东西 - SET QUOTED_IDENTIFIER 切换。我会修改答案,因为无论如何我更喜欢方括号,我刚刚遵循了 OP 问题的风格。

以上是关于创建表时声明默认约束的主要内容,如果未能解决你的问题,请参考以下文章

创建表和添加表约束

在oracle中如何使用sql语句创建默认约束

Django:在运行单元测试之前创建测试表时“无法添加外键约束”

数据库原理与应用(SQL Server)笔记 第六章 数据完整性

mySQL 约束 (Constraints)

mysql唯一约束