(1 row(s) affected)
Test1Col
-----------
(1 row(s) affected)
Test2Col
-----------
当创建了本地或全局临时表后,CREATE TABLE
语法将支持除 FOREIGN KEY 约束以外的其他所有约束定义。 如果临时表中指定了 FOREIGN KEY 约束,则该语句将返回一条表明已跳过此约束的警告消息。 此表仍将创建,但不使用 FOREIGN KEY 约束。 在 FOREIGN KEY 约束中不能引用临时表。
如果某个临时表是使用命名约束创建的,并且该临时表是在用户定义的事务的作用域内创建的,则一次只能有一个用户执行创建该临时表的语句。 例如,如果某一存储过程使用命名主键约束创建一个临时表,则多个用户无法同时执行该存储过程。
数据库作用域内全局临时表(Azure SQL 数据库)
SQL server 的全局临时表(以 ## 表名开始)存储在 tempdb
中,在整个 SQL Server 实例的所有用户会话之间共享。 有关 SQL 表类型的信息,请参阅上述“创建表”章节。
Azure SQL 数据库支持存储在 tempdb
中且作用域为数据库级别的全局临时表。 也就是说,全局临时表对同一 Azure SQL 数据库 中的所有用户会话进行共享。 其他数据库中的用户会话无法访问全局临时表。
Azure SQL 数据库的全局临时表遵循 SQL Server 对临时表使用的相同语法和语义。 同样,全局临时存储过程也在 Azure SQL 数据库中将范围限定为数据库级别。 局部临时表(表名以 # 开头)也受 Azure SQL 数据库支持,并遵循 SQL Server 使用的相同语法和语义。 请参阅上述临时表章节。
此功能适用于 Azure SQL 数据库。
排查 Azure SQL 数据库的全局临时表存在的问题
有关 tempdb
疑难解答,请参阅如何监视 tempdb 使用情况。
只有服务器管理员才能访问 Azure SQL 数据库中的疑难解答 DMV。
任何用户都可以创建全局临时对象。 用户只能访问自己的对象,除非他们获得更多的权限。
使用 CREATE TABLE 创建已分区表前,必须首先创建分区函数以指定表分区的方式。 分区函数是使用 CREATE PARTITION FUNCTION 创建的。 其次,必须创建分区架构,以指定将保存由分区函数指示的分区的文件组。 分区方案是使用 CREATE PARTITION SCHEME 创建的。 对于已分区表,不能指定用于分隔文件组的 PRIMARY KEY 或 UNIQUE 约束的位置。 有关详细信息,请参阅 Partitioned Tables and Indexes。
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。
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 用户定义类型。
参与构造外键关系的列必须定义为具有同一长度和小数位数。
DEFAULT 定义
每列只能有一个 DEFAULT 定义。
DEFAULT 定义可以包含常量值、函数、SQL 标准 niladic 函数或 NULL。 下表显示 niladic 函数及其在执行 INSERT 语句时返回的默认值。
SQL-92 niladic 函数
DEFAULT 定义中的 constant_expression 不能引用表中的其他列,也不能引用其他表、视图或存储过程。
不能对数据类型为 timestamp 的列或具有 IDENTITY 属性的列创建 DEFAULT 定义。
如果别名数据类型绑定到默认对象,则不能对该别名数据类型的列创建 DEFAULT 定义。
CHECK 约束
列可以有任意多个 CHECK 约束,并且约束条件中可以包含用 AND 和 OR 组合起来的多个逻辑表达式。 列上的多个 CHECK 约束按创建顺序进行验证。
搜索条件必须取值为布尔表达式,并且不能引用其他表。
列级 CHECK 约束只能引用被约束的列,表级 CHECK 约束只能引用同一表中的列。
当执行 INSERT 和 UPDATE 语句时,CHECK CONSTRAINTS 和规则具有相同的数据验证功能。
当列上存在规则和一个或多个 CHECK 约束时,将验证所有限制。
不能在 text、ntext 或 image 列上定义 CHECK 约束。
无法使用 DROP INDEX
删除为约束创建的索引;必须使用 ALTER TABLE
来删除约束。 可以使用 ALTER INDEX ... REBUILD
重新生成已创建的约束用索引。 有关详细信息,请参阅 重新组织和重新生成索引。
除了不能以数字符号 (#) 开头以外,约束名称还必须符合标识符规则。 如果未提供 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_help
或 sp_helpconstraint
。 若要重命名表,请使用 sp_rename
。 若要获得依赖于表的视图和存储过程的报表,请使用 sys.dm_sql_referenced_entities 和 sys.dm_sql_referencing_entities。
表定义中的为 Null 性规则
列的为 Null 性决定该列中是否允许以空值 (NULL
) 作为其数据。 NULL
不为零或空白:NULL
表示没有生成任何项或没有提供显式 NULL
,它通常暗指该值未知或不可用。
使用 CREATE TABLE
或 ALTER TABLE
来创建或更改表时,数据库和会话设置会影响并且可能会替代列定义中所用的数据类型的为 Null 性。 建议您始终将列显式定义为非计算列的 NULL 或 NOT NULL,或者,如果使用用户定义的数据类型,则建议您允许该列使用此数据类型的默认为空性。 稀疏列必须始终允许 NULL。
如果未显式指定列的为 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 OLE DB 驱动程序都默认将 ANSI_NULL_DFLT_ON 设置为 ON。 ODBC 和 OLE DB 用户可以在 ODBC 数据源中配置该设置,或通过应用程序设置的连接特性或属性配置该设置。
无法为系统表启用压缩。 在创建表时,除非另外指定,否则,将数据压缩设置为 NONE。 如果指定的分区列表或分区超出范围,将生成错误。 有关数据压缩的详细信息,请参阅 数据压缩。
若要评估更改压缩状态将对表、索引或分区有何影响,请使用 sp_estimate_data_compression_savings 存储过程。
需要在数据库中具有 CREATE TABLE
权限,以及对创建表所在的架构具有 ALTER
权限。
如果 CREATE TABLE
语句中的任何列被定义为用户定义类型,则需要对用户定义类型具有 REFERENCES
权限。
如果 CREATE TABLE
语句中的任何列被定义为 CLR 用户定义类型,则需要具有对此类型的所有权或 REFERENCES
权限。
如果 CREATE TABLE
语句中的任何列具有与其关联的 XML 架构集合,则需要具有对 XML 架构集合的所有权或 REFERENCES
权限。
任何用户都可以在 tempdb
中创建临时表。
如果该语句创建了一个分类帐表,则需要 ENABLE LEDGER
权限。
A. 对列创建 PRIMARY KEY 约束
以下示例显示对 EmployeeID
表的 Employee
列具有聚集索引的 PRIMARY KEY 约束的列定义。 因为未指定约束名称,所以系统提供了约束名称。
CREATE TABLE dbo.Employee (
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)
多列键约束作为表约束创建。 在 AdventureWorks2022
数据库中,SpecialOfferProduct
表包含多列 PRIMARY KEY。 以下示例显示如何从其他表中引用此键(可选择显式约束名)。
CONSTRAINT FK_SpecialOfferProduct_SalesOrderDetail
FOREIGN KEY (ProductID, SpecialOfferID)
REFERENCES SpecialOfferProduct (ProductID, SpecialOfferID)
C. 使用 UNIQUE 约束
UNIQUE 约束用于强制非主键列的唯一性。 以下示例强制的限制是,Name
表的 Product
列必须唯一。
Name NVARCHAR(100) NOT NULL
UNIQUE NONCLUSTERED
D. 使用 DEFAULT 定义
使用 INSERT 和 UPDATE 语句时,如果没有提供值,则默认值会提供值。 例如,AdventureWorks2022
数据库可包括一个查找表,此表列出该公司的员工可以填充的不同工作。 在描述每个工作的列的下面,如果没有显式输入实际的描述,则字符串默认值可提供一个描述。
DEFAULT 'New Position - title not formalized yet'
除了常量以外,DEFAULT 定义还可以包含函数。 使用以下示例获取输入项的当前日期。
DEFAULT (GETDATE())
niladic 函数扫描也可改善数据完整性。 若要跟踪插入行的用户,请使用 USER 的 niladic 函数。 不要用括号将 niladic 函数括起来。
DEFAULT USER
E. 使用 CHECK 约束
以下示例显示对于在 CreditRating
表的 Vendor
列中输入的值所做的限制。 此约束未命名。
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. 显示完整的表定义
以下示例显示在 AdventureWorks2022
数据库中创建的 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
数据类型的每个实例只能包含一个顶级元素。
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);
CREATE PARTITION SCHEME myRangePS1
AS PARTITION myRangePF1
TO (test1fg, test2fg, test3fg, test4fg);
CREATE TABLE PartitionTable (col1 int, col2 char(10))
ON myRangePS1 (col1);
根据 col1
的 PartitionTable
列的值,将分区按照下列方式分配。
test1fg
test2fg
test3fg
test4fg
I. 在列中使用 UNIQUEIDENTIFIER 数据类型
下面的示例创建一个包含 uniqueidentifier
列的表。 该示例使用 PRIMARY KEY 约束以确保用户不会在表中插入重复的值,并在 NEWSEQUENTIALID()
约束中使用 DEFAULT
函数为新行提供值。 将 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. 对计算列使用表达式
以下示例显示如何使用用于计算 (low + high)/2
计算列的表达式 (myavg
)。
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 函数
以下示例在 USER_NAME()
列中使用 myuser_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 dbo.T1
c1 INT,
c2 NVARCHAR(200)
WITH (DATA_COMPRESSION = ROW);
有关其他数据压缩示例,请参阅数据压缩。
O. 创建使用 XML 压缩的表
适用于:SQL Server 2022 (16.x) 及更高版本和 Azure SQL 数据库。
下面的示例创建一个使用行压缩的表。
CREATE TABLE dbo.T1
c1 INT,
c2 XML
WITH (XML_COMPRESSION = ON);
P. 创建具有稀疏列和列集的表
下面的示例说明了如何创建具有稀疏列的表,以及具有两个稀疏列和一个列集的表。 这些示例使用基本语法。 有关更复杂的示例,请参阅使用稀疏列和使用列集。
此示例创建一个包含稀疏列的表。
CREATE TABLE dbo.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
Q. 创建由系统版本控制的、基于磁盘的临时表
适用于:SQL Server 2016 (13.x) 及更高版本和 Azure SQL 数据库。
下列示例显示如何创建链接到新历史记录表的临时表,以及如何创建链接到现有历史记录表的临时表。 临时表须有主键,定义为为表启用和为系统版本控制启用。 有关显示如何在现有表中添加或删除系统版本控制的示例,请参阅示例中的系统版本控制。 有关使用情况,请参阅临时表。
此例表示创建链接到新历史记录表的新临时表。
CREATE TABLE Department
DepartmentNumber CHAR(10) NOT NULL PRIMARY KEY CLUSTERED,
DepartmentName VARCHAR(50) NOT NULL,
ManagerID INT NULL,
ParentDepartmentNumber CHAR(10) NULL,
ValidFrom DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
ValidTo DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
WITH (SYSTEM_VERSIONING = ON);
此例表示创建链接到现有历史记录表的新临时表。
-- Existing table
CREATE TABLE Department_History
DepartmentNumber CHAR(10) NOT NULL,
DepartmentName VARCHAR(50) NOT NULL,
ManagerID INT NULL,
ParentDepartmentNumber CHAR(10) NULL,
ValidFrom DATETIME2 NOT NULL,
ValidTo DATETIME2 NOT NULL
-- Temporal table
CREATE TABLE Department
DepartmentNumber CHAR(10) NOT NULL PRIMARY KEY CLUSTERED,
DepartmentName VARCHAR(50) NOT NULL,
ManagerID INT NULL,
ParentDepartmentNumber CHAR(10) NULL,
ValidFrom DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
ValidTo DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.Department_History, DATA_CONSISTENCY_CHECK = ON));
R. 创建系统版本控制的内存优化临时表
适用于:SQL Server 2016 (13.x) 及更高版本和 Azure SQL 数据库。
下列示例显示如何创建链接到基于磁盘的新历史记录表的新系统版本控制的内存优化临时表。
此例表示创建链接到新历史记录表的新临时表。
CREATE SCHEMA History;
CREATE TABLE dbo.Department
DepartmentNumber CHAR(10) NOT NULL PRIMARY KEY NONCLUSTERED,
DepartmentName VARCHAR(50) NOT NULL,
ManagerID INT NULL,
ParentDepartmentNumber CHAR(10) NULL,
ValidFrom DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
ValidTo DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
MEMORY_OPTIMIZED = ON,
DURABILITY = SCHEMA_AND_DATA,
SYSTEM_VERSIONING = ON (HISTORY_TABLE = History.DepartmentHistory)
此例表示创建链接到现有历史记录表的新临时表。
-- Existing table
CREATE TABLE Department_History
DepartmentNumber CHAR(10) NOT NULL,
DepartmentName VARCHAR(50) NOT NULL,
ManagerID INT NULL,
ParentDepartmentNumber CHAR(10) NULL,
ValidFrom DATETIME2 NOT NULL,
ValidTo DATETIME2 NOT NULL
-- Temporal table
CREATE TABLE Department
DepartmentNumber CHAR(10) NOT NULL PRIMARY KEY CLUSTERED,
DepartmentName VARCHAR(50) NOT NULL,
ManagerID INT NULL,
ParentDepartmentNumber CHAR(10) NULL,
ValidFrom DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
ValidTo DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.Department_History, DATA_CONSISTENCY_CHECK = ON)
S. 创建具有加密列的表
下列示例表示创建包含两个加密列的表。 有关详细信息,请参阅 Always Encrypted。
CREATE TABLE Customers (
CustName NVARCHAR(60)
ENCRYPTED WITH (
COLUMN_ENCRYPTION_KEY = MyCEK,
ENCRYPTION_TYPE = RANDOMIZED,
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256'
SSN VARCHAR(11) COLLATE Latin1_General_BIN2
ENCRYPTED WITH (
COLUMN_ENCRYPTION_KEY = MyCEK,
ENCRYPTION_TYPE = DETERMINISTIC ,
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256'
Age INT NULL
T. 创建内联筛选索引
创建内联已筛选索引的表。
CREATE TABLE t1
c1 INT,
index IX1 (c1) WHERE c1 > 0
U. 创建内联索引
下面演示如何为基于磁盘的表使用 NONCLUSTERED 内联:
CREATE TABLE t1
c1 INT,
INDEX ix_1 NONCLUSTERED (c1)
CREATE TABLE t2
c1 INT,
c2 INT INDEX ix_1 NONCLUSTERED
CREATE TABLE t3
c1 INT,
c2 INT,
INDEX ix_1 NONCLUSTERED (c1,c2)
V. 创建包含匿名复合主键的临时表
创建包含匿名复合主键的临时表。 这有助于避免发生以下运行时冲突:两个会话范围内临时表(分别位于单独的会话中)对约束的命名相同。
CREATE TABLE #tmp
c1 INT,
c2 INT,
PRIMARY KEY CLUSTERED ([c1], [c2])
如果显式命名约束,另一个会话就会生成如下错误:
Msg 2714, Level 16, State 5, Line 1
There is already an object named 'PK_#tmp' in the database.
Msg 1750, Level 16, State 1, Line 1
Could not create constraint or index. See previous errors.
之所以会出现问题是因为,虽然临时表名称是唯一的,但约束名称并不是唯一的。
W. 使用 Azure SQL 数据库中的全局临时表
会话 A 在 Azure SQL 数据库 testdb1 中创建全局临时表 ##test,并添加 1 行
CREATE TABLE ##test (
a INT,
b INT
INSERT INTO ##test
VALUES (1, 1);
-- Obtain object ID for temp table ##test
SELECT OBJECT_ID('tempdb.dbo.##test') AS 'Object ID';
下面是结果集:
1253579504
获取 tempdb
(2) 中给定对象 ID 1253579504 的全局临时表名称
SELECT name FROM tempdb.sys.objects WHERE object_id = 1253579504;
下面是结果集。
##test
会话 B 连接到 Azure SQL 数据库 testdb1,并能访问会话 A 创建的 ##test 表
SELECT * FROM ##test;
下面是结果集。
会话 C 连接到 Azure SQL 数据库 testdb2 中的另一个数据库,并希望访问在 testdb1 中创建的 ##test 表。 此选择因全局临时表的数据库作用域而失败
SELECT * FROM ##test
这将生成以下错误:
Msg 208, Level 16, State 0, Line 1
Invalid object name '##test'
在当前用户数据库 testdb1 中查找 Azure SQL 数据库 tempdb
中的系统对象
SELECT * FROM tempdb.sys.objects;
SELECT * FROM tempdb.sys.columns;
SELECT * FROM tempdb.sys.database_files;
X. 对表启用数据保留策略
以下示例创建了一个表,该表启用了数据保留,并且保留期为 1 周。 此示例仅适用于 Azure SQL Edge。
CREATE TABLE [dbo].[data_retention_table]
[dbdatetime2] datetime2(7),
[product_code] int,
[value] char(10)
WITH (DATA_DELETION = ON ( FILTER_COLUMN = [dbdatetime2], RETENTION_PERIOD = 1 WEEKS ))
Y. 创建可更新的账本表
以下示例创建一个可更新的分类帐表,该表不是具有匿名历史记录表(系统将生成历史记录表的名称)和生成的分类帐视图名称的时态表。 由于未指定所需的 generated always 列以及分类帐视图中其他列的名称,因此这些列将使用默认名称。
CREATE SCHEMA [HR];
CREATE TABLE [HR].[Employees]
EmployeeID INT NOT NULL,
Salary Money NOT NULL
WITH (SYSTEM_VERSIONING = ON, LEDGER = ON);
以下示例创建一个表,该表既是时态表,也是可更新的分类帐表,该表包含匿名历史记录表(其名称由系统生成)、生成的分类帐视图名称和 generated always 列的默认名称,以及附加分类帐视图列。
CREATE SCHEMA [HR];
CREATE TABLE [HR].[Employees]
EmployeeID INT NOT NULL PRIMARY KEY,
Salary Money NOT NULL,
ValidFrom DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
ValidTo DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
WITH (SYSTEM_VERSIONING = ON, LEDGER = ON);
以下示例创建一个表,该表既是时态表,也是可更新的分类帐表,该表包含显式命名的历史记录表、分类帐视图的用户指定名称,以及 generated always 列和分类帐视图中其他列的用户指定名称。
CREATE SCHEMA [HR];
CREATE TABLE [HR].[Employees]
EmployeeID INT NOT NULL PRIMARY KEY,
Salary Money NOT NULL,
StartTransactionId BIGINT GENERATED ALWAYS AS TRANSACTION_ID START HIDDEN NOT NULL,
EndTransactionId BIGINT GENERATED ALWAYS AS TRANSACTION_ID END HIDDEN NULL,
StartSequenceNumber BIGINT GENERATED ALWAYS AS SEQUENCE_NUMBER START HIDDEN NOT NULL,
EndSequenceNumber BIGINT GENERATED ALWAYS AS SEQUENCE_NUMBER END HIDDEN NULL,
ValidFrom DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
ValidTo DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
WITH (
SYSTEM_VERSIONING = ON (HISTORY_TABLE = [HR].[EmployeesHistory]),
LEDGER = ON (
LEDGER_VIEW = [HR].[EmployeesLedger] (
TRANSACTION_ID_COLUMN_NAME = TransactionId,
SEQUENCE_NUMBER_COLUMN_NAME = SequenceNumber,
OPERATION_TYPE_COLUMN_NAME = OperationId,
OPERATION_TYPE_DESC_COLUMN_NAME = OperationTypeDescription
以下示例创建一个仅追加分类帐表,该表包含分类帐视图的生成名称和分类帐视图中的列。
CREATE SCHEMA [AccessControl];
CREATE TABLE [AccessControl].[KeyCardEvents]
EmployeeID INT NOT NULL,
AccessOperationDescription NVARCHAR (MAX) NOT NULL,
[Timestamp] Datetime2 NOT NULL,
StartTransactionId BIGINT GENERATED ALWAYS AS TRANSACTION_ID START HIDDEN NOT NULL,
StartSequenceNumber BIGINT GENERATED ALWAYS AS SEQUENCE_NUMBER START HIDDEN NOT NULL
WITH (
LEDGER = ON (
LEDGER_VIEW = [AccessControl].[KeyCardEventsLedger] (
TRANSACTION_ID_COLUMN_NAME = TransactionId,
SEQUENCE_NUMBER_COLUMN_NAME = SequenceNumber,
OPERATION_TYPE_COLUMN_NAME = OperationId,
OPERATION_TYPE_DESC_COLUMN_NAME = OperationTypeDescription
APPEND_ONLY = ON
以下示例使用默认设置在 Azure SQL 数据库中创建了分类帐数据库,并创建了可更新的分类帐表。 在分类帐数据库中创建可更新的分类帐表不需要使用 WITH (SYSTEM_VERSIONING = ON, LEDGER = ON);
。
CREATE DATABASE MyLedgerDB ( EDITION = 'GeneralPurpose' ) WITH LEDGER = ON;
CREATE SCHEMA [HR];
CREATE TABLE [HR].[Employees]
EmployeeID INT NOT NULL,
Salary Money NOT NULL
ALTER TABLE
COLUMNPROPERTY
CREATE INDEX
CREATE VIEW
DROP INDEX
sys.dm_sql_referenced_entities
sys.dm_sql_referencing_entities
DROP TABLE
CREATE PARTITION FUNCTION
CREATE PARTITION SCHEME
CREATE TYPE
EVENTDATA
sp_help
sp_helpconstraint
sp_rename
sp_spaceused