默认约束完整形式

DEFAULT CONSTRAINT full form

对于每个table约束,我看到有shorthand形式,semi-shorthand 形式和 完整 形式(请原谅我的命名。欢迎提出如何正确称呼它们的建议)

例如

Shorthand形式:让约束名由SQL服务器定义,受影响的列隐含为被定义的列

CREATE TABLE myTable
(
    id int PRIMARY KEY,
)

Semi-shorthand形式:显式约束名,隐含列

id int CONSTRAINT PK_ID PRIMARY KEY,

完整形式:都是显式的。允许在末尾定义与列定义分开

id int,
Name varchar(40),
CONSTRAINT PK_ID PRIMARY KEY(id)

据我所知,完整形式经常出现在 ALTER TABLE 中,其中约束是在之后定义的。

对于DEFAULT约束

速记形式

id int DEFAULT newid()

半shorthand形式

id int CONSTRAINT DF_ID DEFAULT newid()

我在 ALTER TABLE 中看到完整形式的用法,如 here

ALTER TABLE [dbo].[Customers] WITH NOCHECK ADD 
  CONSTRAINT [DF__Customers__cust___151B244E] 
  DEFAULT ('new customer') FOR [cust_name],
  CONSTRAINT [def_last_updated_by] DEFAULT 
  (suser_sname()) FOR [last_updated_by],
  PRIMARY KEY  CLUSTERED 
  ([cust_id])  ON [PRIMARY] 
GO

但是,创建 table 时的完整格式定义失败

CREATE TABLE testGUIDs
(
    ID uniqueidentifier,
    Name varchar(40),
    CONSTRAINT DF_ID DEFAULT newid() FOR [ID]
)
GO

出现错误

Msg 102, Level 15, State 1, Line 5 Incorrect syntax near 'for'.

任何人都可以建议为什么会出现此错误以及如何使用默认约束的完整形式定义?

您需要在列旁边声明它

CREATE TABLE testGUIDs
(
    ID uniqueidentifier CONSTRAINT DF_ID DEFAULT newid(),
    Name varchar(40)    
)
GO

默认约束只能应用于单个列。

table_constraint 的语法不包含 Default,因此可以在最后声明它。

  1. id int PRIMARY KEY只能应用于单场PK。系统为约束指定了一个默认名称。如果您稍后需要该名称来操作约束,但您不知道该名称,这将是一个问题。
  2. id int CONSTRAINT PK_ID PRIMARY KEY只能应用于单场PK
  3. CONSTRAINT PK_ID PRIMARY KEY(col1, col2) 可以应用于复合主键。

至于你的问题:为什么不使用内联变体?无论如何,默认约束只能应用于单个列。根本不支持您的语法。

错误发生是因为 CREATE TABLE 命令中默认约束的语法与 ALTER TABLE 中的不同。不能仅仅因为一个命令使用一种语法就认为它对所有命令都相同。

CREATE TABLE 命令中,语法要求在列后定义默认约束:

<column_definition> ::=column_name <data_type>
...
[ CONSTRAINT constraint_name ] DEFAULT constant_expression ] 
...

与constant_expression定义为:

Is a constant, NULL, or a system function that is used as the default value for the column.

但在 ALTER TABLE 中语法是:

...
| ADD <table_constraint> 
...

table_contraint 的语法是:

[ CONSTRAINT constraint_name ] 
{ 
    ...
    | DEFAULT constant_expression FOR column [ WITH VALUES ] 
    ...
}

可以在单个 ALTER TABLE 命令中定义许多更改,因此需要指定列名。

所以 CREATE TABLE 没有 "full form" 语法。