【问题标题】:DEFAULT CONSTRAINT full form默认约束完整形式
【发布时间】:2015-07-29 20:56:15
【问题描述】:

对于每个表约束,我看到有 shorthand 形式,semi-shorthand 形式和 full 形式(请原谅我的命名. 欢迎提出正确称呼方式的建议)

例如

简写形式:让约束名由SQL Server定义,被影响的列隐含为被定义的列

CREATE TABLE myTable
(
    id int PRIMARY KEY,
)

半简写形式:显式约束名,隐含列

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

半速记形式

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

但是,创建表时的全格式定义失败

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

有错误

消息 102,级别 15,状态 1,第 5 行 'for' 附近的语法不正确。

谁能建议为什么会发生这个错误以及如何使用默认约束的完整形式定义?

【问题讨论】:

    标签: sql-server constraints default default-constraint


    【解决方案1】:

    因为CREATE TABLE 命令中的默认约束的语法与ALTER TABLE 中的不同,所以出现该错误。仅仅因为一个命令使用一种语法,你不能假设它对所有命令都是相同的。

    CREATE TABLE 命令中,语法要求在列之后定义一个具有默认值的约束:

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

    将constant_expression定义为:

    是常量、NULL 或用作默认值的系统函数 列的值。

    但在ALTER TABLE 中,语法是:

    ...
    | ADD <table_constraint> 
    ...
    

    table_contraint 的语法是:

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

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

    所以CREATE TABLE 没有“完整形式”语法。

    【讨论】:

      【解决方案2】:

      您需要在列旁边声明它

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

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

      table_constraint 的语法不包括 Default,这将允许在最后声明它。

      【讨论】:

        【解决方案3】:
        1. id int PRIMARY KEY 只能应用于单场PK。约束由系统赋予一个默认名称。如果您稍后需要名称来操作约束并且您不知道名称,这将是一个问题。
        2. id int CONSTRAINT PK_ID PRIMARY KEY 只能应用于单字段 PK。
        3. CONSTRAINT PK_ID PRIMARY KEY(col1, col2) 可以应用于复合主键。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-11
          • 2012-06-18
          • 2012-07-11
          • 2021-08-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多