CREATE TABLE (Transact-SQL)

创建新表。

主题链接图标Transact-SQL 语法约定

语法

CREATE TABLE 
    [ database_name . [ schema_name ] . | schema_name . ] table_name 
        ( { <column_definition> | <computed_column_definition> 
                | <column_set_definition> }
        [ <table_constraint> ] [ ,...n ] ) 
    [ ON { partition_scheme_name ( partition_column_name ) | filegroup 
        | "default" } ] 
    [ { TEXTIMAGE_ON { filegroup | "default" } ] 
    [ FILESTREAM_ON { partition_scheme_name | filegroup 
        | "default" } ]
    [ WITH ( <table_option> [ ,...n ] ) ]
[ ; ]

<column_definition> ::=
column_name <data_type>
    [ FILESTREAM ]
    [ COLLATE collation_name ] 

    [ SPARSE ] 

    [ NULL | NOT NULL ]
    [ 
        [ CONSTRAINT constraint_name ] DEFAULT constant_expression ] 
      | [ IDENTITY [ ( seed ,increment ) ] [ NOT FOR REPLICATION ] 
    ]
    [ ROWGUIDCOL ] [ <column_constraint> [ ...n ] ] 
<data type> ::= 
[ type_schema_name . ] type_name 
    [ ( precision [ , scale ] | max | 
        [ { CONTENT | DOCUMENT } ] xml_schema_collection ) ] 

<column_constraint> ::= 

[ CONSTRAINT constraint_name ] 
{     { PRIMARY KEY | UNIQUE } 
        [ CLUSTERED | NONCLUSTERED ] 
        [ 
            WITH FILLFACTOR = fillfactor  
          | WITH ( < index_option > [ , ...n ] ) 
        ] 
        [ ON { partition_scheme_name ( partition_column_name ) 
            | filegroup | "default" } ]
  | [ FOREIGN KEY ] 
        REFERENCES [ schema_name . ] referenced_table_name [ ( ref_column ) ] 
        [ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] 
        [ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] 
        [ NOT FOR REPLICATION ] 
  | CHECK [ NOT FOR REPLICATION ] ( logical_expression ) 
} 

<computed_column_definition> ::=
column_name AS computed_column_expression 
[ PERSISTED [ NOT NULL ] ]
[ 
    [ CONSTRAINT constraint_name ]
    { PRIMARY KEY | UNIQUE }
        [ CLUSTERED | NONCLUSTERED ]
        [ 
            WITH FILLFACTOR = fillfactor 
          | WITH ( <index_option> [ , ...n ] )
        ]
    | [ FOREIGN KEY ] 
        REFERENCES referenced_table_name [ ( ref_column ) ] 
        [ ON DELETE { NO ACTION | CASCADE } ] 
        [ ON UPDATE { NO ACTION } ] 
        [ NOT FOR REPLICATION ] 
    | CHECK [ NOT FOR REPLICATION ] ( logical_expression ) 
    [ ON { partition_scheme_name ( partition_column_name ) 
        | filegroup | "default" } ]
] 

<column_set_definition> ::=
column_set_name XML COLUMN_SET FOR ALL_SPARSE_COLUMNS

< table_constraint > ::=
[ CONSTRAINT constraint_name ] 
{ 
    { PRIMARY KEY | UNIQUE } 
        [ CLUSTERED | NONCLUSTERED ] 

                (column [ ASC | DESC ] [ ,...n ] ) 
        [ 
            WITH FILLFACTOR = fillfactor 
           |WITH ( <index_option> [ , ...n ] ) 
        ]
        [ ON { partition_scheme_name (partition_column_name)
            | filegroup | "default" } ] 
    | FOREIGN KEY 
                ( column [ ,...n ] ) 
        REFERENCES referenced_table_name [ ( ref_column [ ,...n ] ) ] 
        [ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] 
        [ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] 
        [ NOT FOR REPLICATION ] 
    | CHECK [ NOT FOR REPLICATION ] ( logical_expression ) 
} 

<table_option> ::=
{
    DATA_COMPRESSION = { NONE | ROW | PAGE }
      [ ON PARTITIONS ( { <partition_number_expression> | <range> } 
            [ , ...n ] ) ]
}

<index_option> ::=
{ 
    PAD_INDEX = { ON | OFF } 
  | FILLFACTOR = fillfactor 
  | IGNORE_DUP_KEY = { ON | OFF } 
  | STATISTICS_NORECOMPUTE = { ON | OFF } 
  | ALLOW_ROW_LOCKS = { ON | OFF} 
  | ALLOW_PAGE_LOCKS ={ ON | OFF} 
  | DATA_COMPRESSION = { NONE | ROW | PAGE }
       [ ON PARTITIONS ( { <partition_number_expression> | <range> } 
       [ , ...n ] ) ]
}
<range> ::= 
<partition_number_expression> TO <partition_number_expression>

参数

  • database_name
    在其中创建表的数据库的名称。database_name 必须指定现有数据库的名称。如果未指定,则 database_name 默认为当前数据库。当前连接的登录名必须与 database_name 所指定数据库中的一个现有用户 ID 关联,并且该用户 ID 必须具有 CREATE TABLE 权限。

  • schema_name
    新表所属架构的名称。

  • table_name
    新表的名称。表名必须遵循标识符规则。除了本地临时表名(以单个数字符号 (#) 为前缀的名称)不能超过 116 个字符外,table_name 最多可包含 128 个字符。

  • column_name
    表中列的名称。列名必须遵循有关标识符的规则,而且在表中必须是唯一的。column_name 最多可包含 128 个字符。对于使用 timestamp 数据类型创建的列,可以省略 column_name。如果未指定 column_name,则 timestamp 列的名称默认为 timestamp。

  • computed_column_expression
    定义计算列的值的表达式。计算列是虚拟列,并非实际存储在表中,除非此列标记为 PERSISTED。该列由同一表中的其他列通过表达式计算得到。例如,计算列可以定义为 cost AS price * qty。表达式可以是非计算列的列名、常量、函数、变量,也可以是用一个或多个运算符连接的上述元素的任意组合。表达式不能是子查询,也不能包含别名数据类型。

    计算列可用于选择列表、WHERE 子句、ORDER BY 子句或任何可使用正则表达式的其他位置,但下列情况除外:

    • 计算列不能用作 DEFAULT 或 FOREIGN KEY 约束定义,也不能与 NOT NULL 约束定义一起使用。但是,如果计算列的值由具有确定性的表达式定义,并且索引列中允许计算结果的数据类型,则可将该列用作索引中的键列,或用作 PRIMARY KEY 或 UNIQUE 约束的一部分。

      例如,如果表中含有整数列 ab,则可以对计算列 a+b 创建索引,但不能对计算列 a+DATEPART(dd, GETDATE()) 创建索引,因为在以后的调用中,其值可能发生改变。

    • 计算列不能作为 INSERT 或 UPDATE 语句的目标。

    注意注意

    表中计算列所使用的列值因行而异,因此计算列的每一行可能有不同的值。

    计算列的为 Null 性是由数据库引擎根据使用的表达式自动确定的。即使只有不可为空的列,大多数表达式的结果也认为是可为空的,因为可能的下溢或溢出也将生成 NULL 结果。使用带 AllowsNull 属性的 COLUMNPROPERTY 函数可查明表中任何计算列的为 Null 性。通过与 check_expression 常量一起指定 ISNULL(其中,常量是替换所有 NULL 结果的非空值),可以将可为空的表达式转换为不可为空的表达式。对于基于公共语言运行时 (CLR) 用户定义类型表达式的计算列,需要对此类型有 REFERENCES 权限。

  • PERSISTED
    指定 SQL Server 数据库引擎将在表中物理存储计算值,而且,当计算列依赖的任何其他列发生更新时对这些计算值进行更新。将计算列标记为 PERSISTED 可允许您对具有确定性、但不精确的计算列创建索引。有关详细信息,请参阅 为计算列创建索引。用作已分区表的分区依据列的所有计算列都必须显式标记为 PERSISTED。指定 PERSISTED 时,computed_column_expression 必须具有确定性。

  • ON { <partition_scheme> | filegroup | "default" }
    指定存储表的分区架构或文件组。如果指定了 <partition_scheme>,则该表将成为已分区表,其分区存储在 <partition_scheme> 所指定的一个或多个文件组的集合中。如果指定了 filegroup,则该表将存储在命名的文件组中。数据库中必须存在该文件组。如果指定了 "default",或者根本未指定 ON,则表存储在默认文件组中。CREATE TABLE 中指定的表的存储机制以后不能进行更改。

    ON {<partition_scheme> | filegroup | default} 也可在 PRIMARY KEY 约束或 UNIQUE 约束中指定。这些约束会创建索引。如果指定了 filegroup,则索引将存储在命名的文件组中。如果指定了 "default",或者根本未指定 ON,则索引将与表存储在同一文件组中。如果 PRIMARY KEY 约束或 UNIQUE 约束创建聚集索引,则表的数据页将与索引存储在同一文件组中。如果指定了 CLUSTERED 或约束另外创建了聚集索引,并且指定的 <partition_scheme> 不同于表定义的 <partition_scheme> 或 filegroup ,或反之,则只接受约束定义,而忽略其他定义。

    注意注意

    在此上下文中,default 不是关键字。它是默认文件组的标识符,并且必须进行分隔(类似于 ON "default" 或 ON[default])。如果指定了 "default",则当前会话的 QUOTED_IDENTIFIER 选项必须为 ON。这是默认设置。有关详细信息,请参阅 SET QUOTED_IDENTIFIER (Transact-SQL)

    注意注意

    在创建分区表后,请考虑将表的 LOCK_ESCALATION 选项设置为 AUTO。这可通过将锁升级到分区 (HoBT) 级而不是表级来改善并发性。有关详细信息,请参阅 ALTER TABLE (Transact-SQL)

  • TEXTIMAGE_ON { filegroup| "default" }
    指示 text、ntext、image、xml、varchar(max)、nvarchar(max)、varbinary(max) 和 CLR 用户定义类型的列存储在指定文件组的关键字。

    如果表中没有较大值的列,则不允许使用 TEXTIMAGE_ON。如果指定了 <partition_scheme>,则不能指定 TEXTIMAGE_ON。如果指定了 "default",或者根本未指定 TEXTIMAGE_ON,则较大值的列存储在默认文件组中。CREATE TABLE 中指定的任何较大值列的数据存储以后都不能进行更改。

    注意注意

    在此上下文中,default 不是关键字。它是默认文件组的标识符,而且必须进行分隔,如 TEXTIMAGE_ON "default" 或 TEXTIMAGE_ON [default] 中所示。如果指定了 "default",则当前会话的 QUOTED_IDENTIFIER 选项必须为 ON。这是默认设置。有关详细信息,请参阅 SET QUOTED_IDENTIFIER (Transact-SQL)

  • FILESTREAM_ON { partition_scheme_name | filegroup | "default" }
    指定 FILESTREAM 数据的文件组。

    如果表包含 FILESTREAM 数据并且已分区,则必须包含 FILESTREAM_ON 子句并指定 FILESTREAM 文件组的分区方案。此分区方案必须使用与表分区方案相同的分区函数和分区列;否则,将引发错误。

    如果该表未分区,则无法对 FILESTREAM 列分区。表的 FILESTREAM 数据必须存储在单个文件组中。此文件组是在 FILESTREAM_ON 子句中指定的。

    如果表未分区并且未指定 FILESTREAM_ON 子句,则使用设置了 DEFAULT 属性的 FILESTREAM 文件组。如果没有 FILESTREAM 文件组,将引发错误。

    • 与 ON 和 TEXTIMAGE_ON 一样,使用 CREATE TABLE 设置的 FILESTREAM_ON 值无法更改,但以下情况除外:

    • CREATE INDEX 语句将堆转换为聚集索引。在这种情况下,可以指定不同的 FILESTREAM 文件组、分区方案或 NULL。

    • DROP INDEX 语句将聚集索引转换为堆。在这种情况下,可以指定不同的 FILESTREAM 文件组、分区方案或 "default"

    FILESTREAM_ON <filegroup> 子句中的文件组或在分区方案中指定的每个 FILESTREAM 文件组必须定义了一个文件。必须使用 CREATE DATABASEALTER DATABASE 语句来定义此文件;否则,将引发错误。

    有关相关的 FILESTREAM 主题,请参阅设计和实现 FILESTREAM 存储

  • [ type_schema_name**.** ] type_name
    指定列的数据类型以及该列所属的架构。数据类型可以是下列类型之一:

    • 系统数据类型。

    • 基于 SQL Server 系统数据类型的别名类型。必须先用 CREATE TYPE 语句创建别名数据类型,然后才能将其用于表定义中。在 CREATE TABLE 语句中,可以覆盖别名数据类型的 NULL 或 NOT NULL 赋值。但是,指定的长度不能更改;不能在 CREATE TABLE 语句中指定别名数据类型的长度。

    • CLR 用户定义类型。必须先用 CREATE TYPE 语句创建 CLR 用户定义类型,然后才能将其用于表定义中。若要创建 CLR 用户定义类型的列,则需要对此类型具有 REFERENCES 权限。

    如果未指定 type_schema_name,则 SQL Server 数据库引擎将按以下顺序引用 type_name:

    • SQL Server 系统数据类型。

    • 当前数据库中当前用户的默认架构。

    • 当前数据库中的 dbo 架构。

  • precision
    指定的数据类型的精度。有关有效精度值的详细信息,请参阅精度、小数位数和长度

  • scale
    是指定数据类型的小数位数。有关有效小数位数值的详细信息,请参阅精度、小数位数和长度

  • max
    只适用于 varchar、nvarchar 和 varbinary 数据类型,用于存储 2^31 个字节的字符和二进制数据,以及 2^30 个字节的 Unicode 数据。

  • CONTENT
    指定 column_name 中每个数据类型为 xml 的实例都可包含多个顶级元素。CONTENT 仅适用于 xml 数据类型,并且只有在同时指定了 xml_schema_collection 时才能指定 CONTENT。如果未指定,则 CONTENT 为默认行为。

  • DOCUMENT
    指定 column_name 中每个数据类型为 xml 的实例都只能包含一个顶级元素。DOCUMENT 仅适用于 xml 数据类型,并且只有同时指定了 xml_schema_collection 时才能指定 DOCUMENT。

  • xml_schema_collection
    仅适用于 xml 数据类型,用于将 XML 架构集合与该类型相关联。在架构中键入 xml 列之前,必须先使用 CREATE XML SCHEMA COLLECTION 在数据库中创建该架构。

  • DEFAULT
    如果在插入过程中未显式提供值,则指定为列提供的值。DEFAULT 定义可适用于除定义为 timestamp 或带 IDENTITY 属性的列以外的任何列。如果为用户定义类型列指定了默认值,则该类型应当支持从 constant_expression 到用户定义类型的隐式转换。删除表时,将删除 DEFAULT 定义。只有常量值(例如字符串)、标量函数(系统函数、用户定义函数或 CLR 函数)或 NULL 可用作默认值。为了与 SQL Server 的早期版本兼容,可以为 DEFAULT 分配约束名称。

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

  • IDENTITY
    指示新列是标识列。在表中添加新行时,数据库引擎将为该列提供一个唯一的增量值。标识列通常与 PRIMARY KEY 约束一起用作表的唯一行标识符。可以将 IDENTITY 属性分配给 tinyint、smallint、int、bigint、decimal(p,0) 或 numeric(p,0) 列。每个表只能创建一个标识列。不能对标识列使用绑定默认值和 DEFAULT 约束。必须同时指定种子和增量,或者两者都不指定。如果二者都未指定,则取默认值 (1,1)。

  • seed
    是装入表的第一行所使用的值。

  • increment
    是向装载的前一行的标识值中添加的增量值。

  • NOT FOR REPLICATION
    在 CREATE TABLE 语句中,可为 IDENTITY 属性、FOREIGN KEY 约束和 CHECK 约束指定 NOT FOR REPLICATION 子句。如果为 IDENTITY 属性指定了该子句,则复制代理执行插入时,标识列中的值将不会增加。如果为约束指定了此子句,则当复制代理执行插入、更新或删除操作时,将不会强制执行此约束。有关详细信息,请参阅使用 NOT FOR REPLICATION 来控制约束、标识和触发器

  • ROWGUIDCOL
    指示新列是行 GUID 列。对于每个表,只能将其中的一个 uniqueidentifier 列指定为 ROWGUIDCOL 列。应用 ROWGUIDCOL 属性将使列能够使用 $ROWGUID 进行引用。ROWGUIDCOL 属性只能分配给 uniqueidentifier 列。如果数据库兼容级别小于或等于 65,则 ROWGUIDCOL 关键字无效。有关详细信息,请参阅 sp_dbcmptlevel (Transact-SQL)。用户定义数据类型列不能使用 ROWGUIDCOL 指定。

    ROWGUIDCOL 属性并不强制列中所存储值的唯一性。ROWGUIDCOL 也不会为插入表的新行自动生成值。若要为每列生成唯一值,请对 INSERT 语句使用 NEWIDNEWSEQUENTIALID 函数,或使用这些函数作为该列的默认值。

  • SPARSE
    指示列为稀疏列。稀疏列已针对 NULL 值进行了存储优化。不能将稀疏列指定为 NOT NULL。有关稀疏列的其他限制和详细信息,请参阅使用稀疏列

  • FILESTREAM
    仅对 varbinary(max) 列有效。请为 varbinary(max) BLOB 数据指定 FILESTREAM 存储。

    表中还必须包含一个具有 ROWGUIDCOL 属性的 uniqueidentifier 数据类型列。此列不得为空值且必须具有 UNIQUE 或 PRIMARY KEY 单列约束。该列的 GUID 值必须由应用程序在插入数据时提供,或者由使用 NEWID () 函数的 DEFAULT 约束提供。

    如果为表定义了 FILESTREAM 列,则不能删除 ROWGUIDCOL 列并且不能更改相关的约束。仅当删除了最后一个 FILESTREAM 列后,才能删除 ROWGUIDCOL 列。

    如果为某个列指定了 FILESTREAM 存储属性,该列的所有值将存储在文件系统上的 FILESTREAM 数据容器中。

  • COLLATE collation_name
    指定列的排序规则。排序规则名称可以是 Windows 排序规则名称或 SQL 排序规则名称。collation_name 只适用于 char、varchar、text、nchar、nvarchar 和 ntext 等数据类型列。如果没有指定该参数,则该列的排序规则是用户定义数据类型的排序规则(如果列为用户定义数据类型)或数据库的默认排序规则。

    有关 Windows 和 SQL 排序规则名称的详细信息,请参阅 Windows 排序规则名称SQL 排序规则名称

    有关 COLLATE 子句的详细信息,请参阅 COLLATE (Transact-SQL)

  • CONSTRAINT
    可选关键字,表示 PRIMARY KEY、NOT NULL、UNIQUE、FOREIGN KEY 或 CHECK 约束定义的开始。有关详细信息,请参阅约束

  • constraint_name
    约束的名称。约束名称必须在表所属的架构中唯一。

  • NULL | NOT NULL
    确定列中是否允许使用空值。严格来讲,NULL 不是约束,但可以像指定 NOT NULL 那样指定它。只有同时指定了 PERSISTED 时,才能为计算列指定 NOT NULL。

  • PRIMARY KEY
    是通过唯一索引对给定的一列或多列强制实体完整性的约束。每个表只能创建一个 PRIMARY KEY 约束。

  • UNIQUE
    一个约束,该约束通过唯一索引为一个或多个指定列提供实体完整性。一个表可以有多个 UNIQUE 约束。

  • CLUSTERED | NONCLUSTERED
    指示为 PRIMARY KEY 或 UNIQUE 约束创建聚集索引还是非聚集索引。PRIMARY KEY 约束默认为 CLUSTERED,UNIQUE 约束默认为 NONCLUSTERED。

    在 CREATE TABLE 语句中,可只为一个约束指定 CLUSTERED。如果在为 UNIQUE 约束指定 CLUSTERED 的同时又指定了 PRIMARY KEY 约束,则 PRIMARY KEY 将默认为 NONCLUSTERED。

  • FOREIGN KEY REFERENCES
    为列中的数据提供引用完整性的约束。FOREIGN KEY 约束要求列中的每个值在所引用的表中对应的被引用列中都存在。FOREIGN KEY 约束只能引用在所引用的表中是 PRIMARY KEY 或 UNIQUE 约束的列,或所引用的表中在 UNIQUE INDEX 内的被引用列。计算列上的外键也必须标记为 PERSISTED。

  • [ schema_name**.**] referenced_table_name]
    是 FOREIGN KEY 约束引用的表的名称,以及该表所属架构的名称。

  • **(**ref_column [ ,... n ] )
    是 FOREIGN KEY 约束所引用的表中的一列或多列。

  • ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT }
    指定如果已创建表中的行具有引用关系,并且被引用行已从父表中删除,则对这些行采取的操作。默认值为 NO ACTION。

    • NO ACTION
      数据库引擎将引发错误,并回滚对父表中行的删除操作。

    • CASCADE
      如果从父表中删除一行,则将从引用表中删除相应行。

    • SET NULL
      如果父表中对应的行被删除,则组成外键的所有值都将设置为 NULL。若要执行此约束,外键列必须可为空值。

    • SET DEFAULT
      如果父表中对应的行被删除,则组成外键的所有值都将设置为默认值。若要执行此约束,所有外键列都必须有默认定义。如果某个列可为空值,并且未设置显式的默认值,则将使用 NULL 作为该列的隐式默认值。

    如果该表将包含在使用逻辑记录的合并发布中,则不要指定 CASCADE。有关逻辑记录的详细信息,请参阅通过逻辑记录对相关行的更改进行分组

    如果表中已存在 ON DELETE 的 INSTEAD OF 触发器,则不能定义 ON DELETE 的 CASCADE 操作。

    例如,在 AdventureWorks 数据库中,ProductVendor 表与 Vendor 表有引用关系。ProductVendor.VendorID 外键引用 Vendor.VendorID 主键。

    如果对 Vendor 表中的行执行 DELETE 语句,并且为 ProductVendor.VendorID 指定了 ON DELETE CASCADE 操作,则数据库引擎将检查 ProductVendor 表中是否有一个或多个依赖行。如果存在依赖行,则 ProductVendor 表中的依赖行将随 Vendor 表中的被引用行一同删除。

    相反,如果指定了 NO ACTION,并且 ProductVendor 表中至少有一行引用 Vendor 行,则数据库引擎将引发错误并回滚对 Vendor 行的删除操作。

  • ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT }
    指定在发生更改的表中,如果行有引用关系且引用的行在父表中被更新,则对这些行采取何种操作。默认值为 NO ACTION。

    • NO ACTION
      数据库引擎将引发错误,并回滚对父表中相应行的更新操作。

    • CASCADE
      如果在父表中更新了一行,则将在引用表中更新相应的行。

    • SET NULL
      如果更新了父表中的相应行,则会将构成外键的所有值设置为 NULL。若要执行此约束,外键列必须可为空值。

    • SET DEFAULT
      如果更新了父表中的相应行,则会将构成外键的所有值都设置为其默认值。若要执行此约束,所有外键列都必须有默认定义。如果某个列可为空值,并且未设置显式的默认值,则将使用 NULL 作为该列的隐式默认值。

    如果该表将包含在使用逻辑记录的合并发布中,则不要指定 CASCADE。有关逻辑记录的详细信息,请参阅通过逻辑记录对相关行的更改进行分组

    如果正在更改的表已经存在 INSTEAD OF 触发器 ON UPDATE,则不能定义 ON UPDATE CASCADE。

    例如,在 AdventureWorks 数据库中,ProductVendor 表和 Vendor 表之间具有如下引用关系:ProductVendor.VendorID 外键引用 Vendor.VendorID 主键。

    如果对 Vendor 表中的行执行 UPDATE 语句,并且为 ProductVendor.VendorID 指定了 ON UPDATE CASCADE 操作,则数据库引擎将检查 ProductVendor 表中的一个或多个依赖行。如果存在依赖行,则 ProductVendor 表中的依赖行将随 Vendor 表中的被引用行一同更新。

    反之,如果指定了 NO ACTION,并且 ProductVendor 表中至少有一行引用 Vendor 行,则数据库引擎将引发错误并回滚对 Vendor 行的更新操作。

  • CHECK
    一个约束,该约束通过限制可输入一列或多列中的可能值来强制实现域完整性。计算列上的 CHECK 约束也必须标记为 PERSISTED。

  • logical_expression
    返回 TRUE 或 FALSE 的逻辑表达式。别名数据类型不能作为表达式的一部分。

  • column
    用括号括起来的一列或多列,在表约束中表示这些列用在约束定义中。

  • [ ASC | DESC ]
    指定加入到表约束中的一列或多列的排序顺序。默认值为 ASC。

  • partition_scheme_name
    分区架构的名称,该分区架构定义要将已分区表的分区映射到的文件组。数据库中必须存在该分区架构。

  • [ partition_column_name**.** ]
    指定对已分区表进行分区所依据的列。该列必须在数据类型、长度和精度方面与 partition_scheme_name 所使用的分区函数中指定的列相匹配。必须将参与分区函数的计算列显式标记为 PERSISTED。

    重要说明重要提示

    建议您对分区表的分区列以及作为 ALTER TABLE...SWITCH 操作源或目标的非分区表指定 NOT NULL。这样做可确保分区列上的所有 CHECK 约束都不必检查 Null 值。有关详细信息,请参阅使用分区切换高效传输数据

  • WITH FILLFACTOR **=**fillfactor
    指定数据库引擎存储索引数据时每个索引页的填充程度。用户指定的 fillfactor 值的范围可以为 1 到 100。如果未指定值,则默认值为 0。填充因子的值 0 和 100 在所有方面都是相同的。

    重要说明重要提示

    将 WITH FILLFACTOR = fillfactor 记录为适用于 PRIMARY KEY 或 UNIQUE 约束的唯一索引选项是为了保持向后兼容,但在未来的版本中将不会以此方式进行记录。

  • column_set_name XML COLUMN_SET FOR ALL_SPARSE_COLUMNS
    列集的名称。列集是一种非类型化的 XML 表示形式,它将表的所有稀疏列合并为一种结构化的输出。有关列集的详细信息,请参阅使用列集

  • < table_option> ::=
    指定一个或多个表选项。

  • DATA_COMPRESSION
    为指定的表、分区号或分区范围指定数据压缩选项。选项如下所示:

    • NONE
      不压缩表或指定的分区。

    • ROW
      使用行压缩来压缩表或指定的分区。

    • PAGE
      使用页压缩来压缩表或指定的分区。

    有关压缩的详细信息,请参阅创建压缩表和索引

  • ON PARTITIONS ( { <partition_number_expression> | <range> } [ ,...n ] )
    指定对其应用 DATA_COMPRESSION 设置的分区。如果表未分区,则 ON PARTITIONS 参数将生成错误。如果不提供 ON PARTITIONS 子句,则 DATA_COMPRESSION 选项将应用于分区表的所有分区。

    可以按以下方式指定 <partition_number_expression>:

    • 提供分区的分区号,例如,ON PARTITIONS (2)。

    • 提供若干单独分区的分区号并用逗号将它们隔开,例如:ON PARTITIONS (1, 5)。

    • 同时提供范围和单个分区,例如,ON PARTITIONS (2, 4, 6 TO 8)。

    <range> 可以指定为以单词 TO 隔开的分区号,例如:ON PARTITIONS (6 TO 8)。

    若要为不同分区设置不同的数据压缩类型,请多次指定 DATA_COMPRESSION 选项,例如:

    WITH 
    (
    DATA_COMPRESSION = NONE ON PARTITIONS (1), 
    DATA_COMPRESSION = ROW ON PARTITIONS (2, 4, 6 TO 8), 
    DATA_COMPRESSION = PAGE ON PARTITIONS (3, 5)
    )
    
  • <index_option> ::=
    指定一个或多个索引选项。有关这些选项的完整说明,请参阅 CREATE INDEX (Transact-SQL)

  • PAD_INDEX = { ON | OFF }
    如果为 ON,则 FILLFACTOR 指定的可用空间百分比将应用于该索引的中间级别页。如果未指定 OFF 或 FILLFACTOR 值,则考虑到中间级别页的键集,将中间级别页填充到一个近似容量,以留出足够的空间来容纳至少一个索引的最大行。默认值为 OFF。

  • FILLFACTOR **=**fillfactor
    指定一个百分比,指示在创建或更改索引期间,数据库引擎对各索引页的叶级填充的程度。fillfactor 必须为介于 1 至 100 之间的整数值。默认值为 0。填充因子的值 0 和 100 在所有方面都是相同的。

  • IGNORE_DUP_KEY = { ON | OFF }
    指定在插入操作尝试向唯一索引插入重复键值时的错误响应。IGNORE_DUP_KEY 选项仅适用于创建或重新生成索引后发生的插入操作。当执行 CREATE INDEXALTER INDEXUPDATE 时,该选项无效。默认值为 OFF。

    • ON
      向唯一索引插入重复键值时将出现警告消息。只有违反唯一性约束的行才将失败。

    • OFF
      向唯一索引插入重复键值时将出现错误消息。整个 INSERT 操作将被回滚。

    对于对视图创建的索引、非唯一索引、XML 索引、空间索引以及筛选的索引,IGNORE_DUP_KEY 不能设置为 ON。

    若要查看 IGNORE_DUP_KEY,请使用 sys.indexes

    在向后兼容的语法中,WITH IGNORE_DUP_KEY 等效于 WITH IGNORE_DUP_KEY = ON。

  • STATISTICS_NORECOMPUTE = { ON | OFF }
    如果为 ON,则过期的索引统计信息不会自动重新计算。如果为 OFF,则启用自动统计信息更新。默认值为 OFF。

  • ALLOW_ROW_LOCKS = { ON | OFF }
    如果为 ON,则访问索引时允许使用行锁。数据库引擎确定何时使用行锁。如果为 OFF,则不使用行锁。默认值为 ON。

  • ALLOW_PAGE_LOCKS = { ON | OFF }
    如果为 ON,则访问索引时允许使用页锁。数据库引擎确定何时使用页锁。如果为 OFF,则不使用页锁。默认值为 ON。

注释

在 SQL Server 2008 中,每个数据库最多可包含 20 亿个表。具有定义的列集的一个表中最多可以包含 30,000 个列,其中最多有 1024 个非稀疏列和计算列。不含列集的表限制为 1024 个列。表的行数及总大小仅受可用存储空间的限制。每行的最大字节数为 8,060。对于带 varchar、nvarchar、varbinary 或 sql_variant 列(导致已定义表的总宽超过 8,060 字节)的表,此限制将放宽。其中每列的长度仍必须在 8,000 字节的限制内,但是它们的总宽可能超过表的 8,060 字节的限制。有关详细信息,请参阅行溢出数据超过 8 KB

每个表最多可以有 999 个非聚集索引和 1 个聚集索引。其中包括为支持表中所定义的 PRIMARY KEY 和 UNIQUE 约束而生成的索引。

通常情况下,为表和索引分配空间时,每次以一个区为增量单位。当创建表或索引时,首先从混合区为其分配页,直到它具有足够的页填满一个统一区。当足够的页填满统一区后,每当当前分配的区填满时,将再为其分配另一个区。若要获得关于由表分配和占用的空间量的报表,请执行 sp_spaceused

数据库引擎在列定义中并不强制以特定的顺序指定 DEFAULT、IDENTITY、ROWGUIDCOL 或列约束。

创建表后,即使 QUOTED IDENTIFIER 选项在创建表时设置为 OFF,该选项在表的元数据中仍存储为 ON。

临时表

可以创建本地临时表和全局临时表。本地临时表仅在当前会话中可见,而全局临时表在所有会话中都可见。临时表不能分区。

本地临时表的名称前面有一个数字符号 (#table_name),而全局临时表的名称前面有两个数字符号 (##table_name)。

SQL 语句使用 CREATE TABLE 语句中为 table_name 指定的值引用临时表,例如:

CREATE TABLE #MyTempTable (cola INT PRIMARY KEY);
INSERT INTO #MyTempTable VALUES (1);

如果在单个存储过程或批处理中创建了多个临时表,则它们必须有不同的名称。

如果本地临时表由存储过程创建或由多个用户同时执行的应用程序创建,则数据库引擎必须能够区分由不同用户创建的表。为此,数据库引擎在内部为每个本地临时表的表名追加一个数字后缀。存储在 tempdbsysobjects 表中的临时表,其全名由 CREATE TABLE 语句中指定的表名和系统生成的数字后缀组成。为了允许追加后缀,为本地临时表名称指定的 table_name 不能超过 116 个字符。

除非使用 DROP TABLE 显式删除临时表,否则临时表将在退出其作用域时由系统自动删除:

  • 当存储过程完成时,将自动删除在存储过程中创建的本地临时表。由创建表的存储过程执行的所有嵌套存储过程都可以引用此表。但调用创建此表的存储过程的进程无法引用此表。

  • 所有其他本地临时表在当前会话结束时都将被自动删除。

  • 全局临时表在创建此表的会话结束且其他所有任务停止对其引用时将被自动删除。任务与表之间的关联只在单个 Transact-SQL 语句的生存周期内保持。换言之,当创建全局临时表的会话结束时,最后一条引用此表的 Transact-SQL 语句完成后,将自动删除此表。

在存储过程或触发器中创建的本地临时表的名称可以与在调用存储过程或触发器之前创建的临时表名称相同。但是,如果查询引用临时表,而同时有两个同名的临时表,则不定义针对哪个表解析该查询。嵌套存储过程同样可以创建与调用它的存储过程所创建的临时表同名的临时表。但是,为了对其进行修改以解析为在嵌套过程中创建的表,此表必须与调用过程创建的表具有相同的结构和列名。下面的示例说明了这一点。

CREATE PROCEDURE dbo.Test2
AS
CREATE TABLE #t(x INT PRIMARY KEY);
INSERT INTO #t VALUES (2);
SELECT Test2Col = x FROM #t;
GO
CREATE PROCEDURE dbo.Test1
AS
CREATE TABLE #t(x INT PRIMARY KEY);
INSERT INTO #t VALUES (1);
SELECT Test1Col = x FROM #t;
EXEC Test2;
GO
CREATE TABLE #t(x INT PRIMARY KEY);
INSERT INTO #t VALUES (99);
GO
EXEC Test1;
GO

下面是结果集。

(1 row(s) affected)

Test1Col    
----------- 
1           

(1 row(s) affected)

Test2Col    
----------- 
2           

当创建本地或全局临时表时,CREATE TABLE 语法支持除 FOREIGN KEY 约束以外的其他所有约束定义。如果临时表中指定了 FOREIGN KEY 约束,则该语句将返回一条表明已跳过此约束的警告消息。此表仍将创建,但不使用 FOREIGN KEY 约束。在 FOREIGN KEY 约束中不能引用临时表。

建议您使用表变量而不使用临时表。当必须对临时表显式地创建索引时,或多个存储过程或函数必须使用表值时,临时表很有用。通常,表变量可提供更有效的查询处理。有关详细信息,请参阅表 (Transact-SQL)

已分区表

使用 CREATE TABLE 创建已分区表前,必须首先创建分区函数以指定表分区的方式。分区函数是使用 CREATE PARTITION FUNCTION 创建的。其次,必须创建分区架构,以指定将保存由分区函数指示的分区的文件组。分区方案是使用 CREATE PARTITION SCHEME 创建的。对于已分区表,不能指定用于分隔文件组的 PRIMARY KEY 或 UNIQUE 约束的位置。有关详细信息,请参阅已分区表和已分区索引

PRIMARY KEY 约束

  • 一个表只能包含一个 PRIMARY KEY 约束。

  • 由 PRIMARY KEY 约束生成的索引不会使表中的非聚集索引超过 999 个,聚集索引超过 1 个。

  • 如果没有为 PRIMARY KEY 约束指定 CLUSTERED 或 NONCLUSTERED,并且没有为 UNIQUE 约束指定聚集索引,则将对该 PRIMARY KEY 约束使用 CLUSTERED。

  • 在 PRIMARY KEY 约束中定义的所有列都必须定义为 NOT NULL。如果没有指定为 Null 性,则加入 PRIMARY KEY 约束的所有列的为 Null 性都将设置为 NOT NULL。

  • 如果在 CLR 用户定义类型的列中定义主键,则该类型的实现必须支持二进制排序。有关详细信息,请参阅 CLR 用户定义类型

UNIQUE 约束

  • 如果没有为 UNIQUE 约束指定 CLUSTERED 或 NONCLUSTERED,则默认使用 NONCLUSTERED。

  • 每个 UNIQUE 约束都生成一个索引。UNIQUE 约束的数目不会使表中的非聚集索引超过 999 个,聚集索引超过 1 个。

  • 如果在 CLR 用户定义类型的列中定义唯一约束,则该类型的实现必须支持二进制或基于运算符的排序。有关详细信息,请参阅 CLR 用户定义类型

FOREIGN KEY 约束

  • 如果在 FOREIGN KEY 约束的列中输入非 NULL 值,则此值必须在被引用列中存在;否则,将返回违反外键约束的错误信息。

  • 如果未指定源列,则 FOREIGN KEY 约束适用于前面所讲的列。

  • FOREIGN KEY 约束仅能引用位于同一服务器上的同一数据库中的表。跨数据库的引用完整性必须通过触发器实现。有关详细信息,请参阅 CREATE TRIGGER (Transact-SQL)

  • FOREIGN KEY 约束可引用同一表中的其他列。此行为称为自引用。

  • 列级 FOREIGN KEY 约束的 REFERENCES 子句只能列出一个引用列。此列的数据类型必须与定义约束的列的数据类型相同。

  • 表级 FOREIGN KEY 约束的 REFERENCES 子句中引用列的数目必须与约束列列表中的列数相同。每个引用列的数据类型也必须与列表中相应列的数据类型相同。

  • 如果类型为 timestamp 的列是外键或被引用键的一部分,则不能指定 CASCADE、SET NULL 或 SET DEFAULT。

  • 可将 CASCADE、SET NULL、SET DEFAULT 和 NO ACTION 在相互存在引用关系的表上进行组合。如果数据库引擎遇到 NO ACTION,它将停止并回滚相关的 CASCADE、SET NULL 和 SET DEFAULT 操作。如果 DELETE 语句导致 CASCADE、SET NULL、SET DEFAULT 和 NO ACTION 操作的组合,则在数据库引擎检查所有 NO ACTION 前,将应用所有 CASCADE、SET NULL 和 SET DEFAULT 操作。

  • 对于表可包含的引用其他表的 FOREIGN KEY 约束的数目或其他表所拥有的引用特定表的 FOREIGN KEY 约束的数目,数据库引擎都没有预定义的限制。

    尽管如此,可使用的 FOREIGN KEY 约束的实际数目还是受硬件配置以及数据库和应用程序设计的限制。建议表中包含的 FOREIGN KEY 约束不要超过 253 个,并且引用该表的 FOREIGN KEY 约束也不要超过 253 个。有效的限制还是或多或少取决于应用程序和硬件。在设计数据库和应用程序时应考虑强制 FOREIGN KEY 约束的开销。

  • 对于临时表不强制 FOREIGN KEY 约束。

  • FOREIGN KEY 约束只能引用所引用的表的 PRIMARY KEY 或 UNIQUE 约束中的列或所引用的表上 UNIQUE INDEX 中的列。

  • 如果在 CLR 用户定义类型的列上定义外键,则该类型的实现必须支持二进制排序。有关详细信息,请参阅 CLR 用户定义类型

  • 仅当 FOREIGN KEY 约束引用的主键也定义为类型 varchar(max) 时,才能在此约束中使用类型为 varchar(max) 的列。

DEFAULT 定义

  • 每列只能有一个 DEFAULT 定义。

  • DEFAULT 定义可以包含常量值、函数、SQL-92 niladic 函数或 NULL。下表显示 niladic 函数及其在执行 INSERT 语句时返回的默认值。

    SQL-92 niladic 函数

    返回的值

    CURRENT_TIMESTAMP

    当前日期和时间。

    CURRENT_USER

    执行插入的用户的名称。

    SESSION_USER

    执行插入的用户的名称。

    SYSTEM_USER

    执行插入的用户的名称。

    USER

    执行插入的用户的名称。

  • DEFAULT 定义中的 constant_expression 不能引用表中的其他列,也不能引用其他表、视图或存储过程。

  • 不能对数据类型为 timestamp 的列或具有 IDENTITY 属性的列创建 DEFAULT 定义。

  • 如果别名数据类型绑定到默认对象,则不能对该别名数据类型的列创建 DEFAULT 定义。

CHECK 约束

  • 列可以有任意多个 CHECK 约束,并且约束条件中可以包含用 AND 和 OR 组合起来的多个逻辑表达式。列上的多个 CHECK 约束按创建顺序进行验证。

  • 搜索条件必须取值为布尔表达式,并且不能引用其他表。

  • 列级 CHECK 约束只能引用被约束的列,表级 CHECK 约束只能引用同一表中的列。

    当执行 INSERT 和 DELETE 语句时,CHECK CONSTRAINTS 和规则具有相同的数据验证功能。

  • 当列上存在规则和一个或多个 CHECK 约束时,将验证所有限制。

  • 不能在 text、ntext 或 image 列上定义 CHECK 约束。

其他约束信息

  • 为约束创建的索引不能用 DROP INDEX 删除;必须用 ALTER TABLE 删除约束。可以用 DBCC DBREINDEX 重建为约束创建的并由其使用的索引。

  • 除了不能以数字符号 (#) 开头以外,约束名称还必须符合标识符规则。如果未提供 constraint_name,则将系统生成的名称分配给约束。约束名将出现在所有与违反约束有关的错误信息中。

  • 当 INSERT、UPDATE 或 DELETE 语句违反约束时,将终止执行该语句。但是,当 SET XACT_ABORT 设置为 OFF 时,如果该语句是显式事务的一部分,则继续处理此事务。当 SET XACT_ABORT 设置为 ON 时,将回滚整个事务。还可以通过检查系统函数 **@@**ERROR,从而在事务定义中使用 ROLLBACK TRANSACTION 语句。

  • 如果 ALLOW_ROW_LOCKS = ON 并且 ALLOW_PAGE_LOCK = ON,则当访问索引时将允许行、页和表级别的锁。数据库引擎将选择相应的锁,并且可以将锁从行锁或页锁升级到表锁。有关详细信息,请参阅锁升级(数据库引擎)。如果 ALLOW_ROW_LOCKS = OFF 并且 ALLOW_PAGE_LOCK = OFF,则当访问索引时只允许表级锁。有关为索引配置锁定粒度的详细信息,请参阅自定义索引的锁定

  • 如果某个表具有 FOREIGN KEY 或 CHECK CONSTRAINTS 及触发器,则将在触发器执行前先检查约束条件。

若要获得关于表及其列的报表,请使用 sp_helpsp_helpconstraint。若要重命名表,请使用 sp_rename。若要获得依赖于表的视图和存储过程的报表,请使用 sys.dm_sql_referenced_entitiessys.dm_sql_referencing_entities

表定义中的为 Null 性规则

列的为 Null 性决定该列中是否允许以空值 (NULL) 作为其数据。NULL 不为零或空白:NULL 表示没有生成任何项或没有提供显式 NULL,它通常暗指该值未知或不可用。

当用 CREATE TABLE 或 ALTER TABLE 语句创建或更改表时,数据库或会话设置会影响且可能覆盖列定义中数据类型的为 Null 性。建议您始终将列显式定义为非计算列的 NULL 或 NOT NULL,或者,如果使用用户定义的数据类型,则建议您允许该列使用此数据类型的默认为空性。稀疏列必须始终允许 NULL。

如果未显式指定列的为 Null 性,则遵循下表显示的规则。

列数据类型

规则

别名数据类型

数据库引擎使用创建数据类型时指定的为 Null 性。若要确定数据类型的默认为 Null 性,请使用 sp_help

CLR 用户定义类型

根据列定义确定为 Null 性。

系统提供的数据类型

如果系统提供的数据类型只有一个选项,则优先使用该选项。timestamp 数据类型必须为 NOT NULL。

当任何会话设置通过 SET 设置为 ON 时:

  • 如果 ANSI_NULL_DFLT_ON = ON,则分配 NULL。

  • 如果 ANSI_NULL_DFLT_OFF = ON,则分配 NOT NULL。

  • 当任何数据库设置通过 ALTER DATABASE 进行配置时:

  • 如果 ANSI_NULL_DEFAULT_ON = ON,则分配 NULL。

  • 如果 ANSI_NULL_DEFAULT_OFF = ON,则分配 NOT NULL。

  • 若要查看 ANSI_NULL_DEFAULT 的数据库设置,请使用 sys.databases 目录视图

如果没有为会话设置任何 ANSI_NULL_DFLT 选项,并且将数据库设置为默认值(ANSI_NULL_DEFAULT 为 OFF),则会分配默认值 NOT NULL。

如果该列是计算列,则其为 Null 性总是由数据库引擎自动确定。若要查找此类型列的为 Null 性,请使用带 AllowsNull 属性的 COLUMNPROPERTY 函数。

注意注意

默认情况下,SQL Server ODBC 驱动程序和用于 SQL Server 的 Microsoft OLE DB 访问接口都将 ANSI_NULL_DFLT_ON 设置为 ON。ODBC 和 OLE DB 用户可以在 ODBC 数据源中配置该设置,或通过应用程序设置的连接特性或属性配置该设置。

数据压缩

不能为系统表启用压缩功能。在创建表时,除非另外指定,否则,将数据压缩设置为 NONE。如果指定的分区列表或分区超出范围,将会生成错误。有关数据压缩的详细信息,请参阅创建压缩表和索引

若要评估更改压缩状态对表、索引或分区造成的影响,请使用 sp_estimate_data_compression_savings 存储过程。

权限

需要在数据库中具有 CREATE TABLE 权限,对在其中创建表的架构具有 ALTER 权限。

如果 CREATE TABLE 语句中的任何列被定义为 CLR 用户定义类型,则需要具有对此类型的所有权或 REFERENCES 权限。

如果 CREATE TABLE 语句中的任何列具有与其关联的 XML 架构集合,则需要具有对 XML 架构集合的所有权或 REFERENCES 权限。

示例

A. 使用 PRIMARY KEY 约束

以下示例显示 AdventureWorks 示例数据库中 Employee 表(允许系统提供约束名)的 EmployeeID 列具有聚集索引的 PRIMARY KEY 约束的列定义。

EmployeeID int
PRIMARY KEY CLUSTERED

B. 使用 FOREIGN KEY 约束

FOREIGN KEY 约束用于引用其他表。FOREIGN KEY 可以是单列键或多列键。以下示例显示 SalesOrderHeader 表上引用 SalesPerson 表的单列 FOREIGN KEY 约束。对于单列 FOREIGN KEY 约束,只需要 REFERENCES 子句。

SalesPersonID int NULL
REFERENCES SalesPerson(SalesPersonID)

也可以显式使用 FOREIGN KEY 子句并复述列特性。注意在这两个表中列名不必相同。

FOREIGN KEY (SalesPersonID) REFERENCES SalesPerson(SalesPersonID)

多列键约束作为表约束创建。在 AdventureWorks 数据库中,SpecialOfferProduct 表包含多列 PRIMARY KEY。以下示例显示如何从其他表中引用此键(可选择显式约束名)。

CONSTRAINT FK_SpecialOfferProduct_SalesOrderDetail FOREIGN KEY
 (ProductID, SpecialOfferID)
REFERENCES SpecialOfferProduct (ProductID, SpecialOfferID)

C. 使用 UNIQUE 约束

UNIQUE 约束用于强制非主键列的唯一性。以下示例强制的限制是,Product 表的 Name 列必须唯一。

Name nvarchar(100) NOT NULL
UNIQUE NONCLUSTERED

D. 使用 DEFAULT 定义

使用 INSERT 和 UPDATE 语句时,如果没有提供值,则默认值会提供值。例如,AdventureWorks 数据库可包括一个查找表,此表列出该公司的员工可以执行的不同工作。在描述每个工作的列的下面,如果没有显式输入实际的描述,则字符串默认值可提供一个描述。

DEFAULT 'New Position - title not formalized yet'

除了常量以外,DEFAULT 定义还可以包含函数。使用以下示例获取输入项的当前日期。

DEFAULT (getdate())

niladic 函数扫描也可以改善数据完整性。若要跟踪插入行的用户,请使用 USER 的 niladic 函数。不要用括号将 niladic 函数括起来。

DEFAULT USER

E. 使用 CHECK 约束

以下示例显示对于在 Vendor 表的 CreditRating 列中输入的值所做的限制。此约束未命名。

CHECK (CreditRating >= 1 and CreditRating <= 5)

此示例显示一个命名约束,它对于在表的列中输入的字符数据有模式限制。

CONSTRAINT CK_emp_id CHECK (emp_id LIKE 
'[A-Z][A-Z][A-Z][1-9][0-9][0-9][0-9][0-9][FM]' 
OR emp_id LIKE '[A-Z]-[A-Z][1-9][0-9][0-9][0-9][0-9][FM]')

此示例指定这些值必须在特定的列表中或遵循指定的模式。

CHECK (emp_id IN ('1389', '0736', '0877', '1622', '1756')
OR emp_id LIKE '99[0-9][0-9]')

F. 显示完整的表定义

以下示例显示在 AdventureWorks 数据库中创建的 PurchaseOrderDetail 表的完整表定义,其中包含所有约束定义。请注意,若要运行此示例,表架构应改为 dbo。

CREATE TABLE [dbo].[PurchaseOrderDetail]
(
    [PurchaseOrderID] [int] NOT NULL
        REFERENCES Purchasing.PurchaseOrderHeader(PurchaseOrderID),
    [LineNumber] [smallint] NOT NULL,
    [ProductID] [int] NULL 
        REFERENCES Production.Product(ProductID),
    [UnitPrice] [money] NULL,
    [OrderQty] [smallint] NULL,
    [ReceivedQty] [float] NULL,
    [RejectedQty] [float] NULL,
    [DueDate] [datetime] NULL,
    [rowguid] [uniqueidentifier] ROWGUIDCOL  NOT NULL
        CONSTRAINT [DF_PurchaseOrderDetail_rowguid] DEFAULT (newid()),
    [ModifiedDate] [datetime] NOT NULL 
        CONSTRAINT [DF_PurchaseOrderDetail_ModifiedDate] DEFAULT (getdate()),
    [LineTotal]  AS (([UnitPrice]*[OrderQty])),
    [StockedQty]  AS (([ReceivedQty]-[RejectedQty])),
CONSTRAINT [PK_PurchaseOrderDetail_PurchaseOrderID_LineNumber]
    PRIMARY KEY CLUSTERED ([PurchaseOrderID], [LineNumber])
    WITH (IGNORE_DUP_KEY = OFF)
) 
ON [PRIMARY];

G. 创建其 xml 列键入 XML 架构集合的表

以下示例创建一个表,其 xml 列将键入 XML 架构集合 HRResumeSchemaCollection。DOCUMENT 关键字指定 column_name 中数据类型为 xml 的每个实例只能包含一个顶级元素。

USE AdventureWorks;
GO
CREATE TABLE HumanResources.EmployeeResumes 
   (LName nvarchar(25), FName nvarchar(25), 
    Resume xml( DOCUMENT HumanResources.HRResumeSchemaCollection) );

H. 创建已分区表

以下示例创建一个分区函数,将表或索引分为四个分区。然后,此示例创建用于指定保存四个分区的文件组的分区架构。最后,此示例创建使用此分区架构的表。此示例假定数据库中已经存在文件组。

CREATE PARTITION FUNCTION myRangePF1 (int)
AS RANGE LEFT FOR VALUES (1, 100, 1000) ;
GO
CREATE PARTITION SCHEME myRangePS1
AS PARTITION myRangePF1
TO (test1fg, test2fg, test3fg, test4fg) ;
GO
CREATE TABLE PartitionTable (col1 int, col2 char(10))
ON myRangePS1 (col1) ;
GO

根据 PartitionTable 的 col1 列的值,将分区按照下列方式分配。

文件组

test1fg

test2fg

test3fg

test4fg

分区

1

2

3

4

col 1 <= 1

col1 > 1 AND col1 <= 100

col1 > 100 AND col1 <= 1,000

col1 > 1000

I. 在列中使用 uniqueidentifier 数据类型

下面的示例创建一个包含 uniqueidentifier 列的表。该示例使用 PRIMARY KEY 约束以确保用户不会在表中插入重复的值,并在 DEFAULT 约束中使用 NEWSEQUENTIALID() 函数为新行提供值。将 ROWGUIDCOL 属性应用到 uniqueidentifier 列,以便可以使用 $ROWGUID 关键字对其进行引用。

CREATE TABLE dbo.Globally_Unique_Data
(guid uniqueidentifier CONSTRAINT Guid_Default DEFAULT NEWSEQUENTIALID() ROWGUIDCOL,
    Employee_Name varchar(60)
CONSTRAINT Guid_PK PRIMARY KEY (guid) );

J. 对计算列使用表达式

以下示例显示如何使用用于计算 myavg 计算列的表达式 ((low + high)/2)。

CREATE TABLE dbo.mytable 
( low int, high int, myavg AS (low + high)/2 ) ;

K. 基于用户定义类型列创建计算列

以下示例将创建一个表,其中一列定义为用户定义类型 utf8string,并假设此类型的程序集和类型本身已在当前数据库中创建。另一列基于 utf8string 定义,使用 type(class)utf8string 的 ToString() 方法计算列值。

CREATE TABLE UDTypeTable 
( u utf8string, ustr AS u.ToString() PERSISTED ) ;

L. 对计算列使用 USER_NAME 函数

以下示例在 myuser_name 列中使用 USER_NAME() 函数。

CREATE TABLE dbo.mylogintable
( date_in datetime, user_id int, myuser_name AS USER_NAME() ) ;

M. 创建具有 FILESTREAM 列的表

下面的示例创建一个包含 FILESTREAM 列 Photo 的表。如果某个表包含一个或多个 FILESTREAM 列,该表必须包含一个 ROWGUIDCOL 列。

CREATE TABLE dbo.EmployeePhoto
    (
    EmployeeId int NOT NULL PRIMARY KEY,
    ,Photo varbinary(max) FILESTREAM NULL
    ,MyRowGuidColumn uniqueidentifier NOT NULL ROWGUIDCOL
        UNIQUE DEFAULT NEWID()
    )

N. 创建使用行压缩的表

下面的示例创建一个使用行压缩的表。

CREATE TABLE T1 
(c1 int, c2 nvarchar(200) )
WITH (DATA_COMPRESSION = ROW);

有关其他数据压缩示例,请参阅创建压缩表和索引

O. 创建具有稀疏列和列集的表

下面的示例说明了如何创建具有稀疏列的表,以及具有两个稀疏列和一个列集的表。这些示例使用基本语法。有关更复杂的示例,请参阅使用稀疏列使用列集

若要创建具有稀疏列的表,请执行以下代码。

CREATE TABLE T1
(c1 int PRIMARY KEY,
C2 varchar(50) SPARSE NULL ) ;

若要创建具有两个稀疏列和一个名为 CSet 的列集的表,请执行以下代码。

CREATE TABLE T1
(c1 int PRIMARY KEY,
C2 varchar(50) SPARSE NULL,
C3 int SPARSE NULL,
CSet XML COLUMN_SET FOR ALL_SPARSE_COLUMNS ) ;