转自:https://docs.microsoft.com/zh-cn/sql/t-sql/statements/alter-database-transact-sql-compatibility-level?view=sql-server-2017
并行数据仓库
ALTER DATABASE (Transact-SQL)。
Transact-SQL 语法约定。
语法
ALTER DATABASE database_name
SET COMPATIBILITY_LEVEL = { 150 | 140 | 130 | 120 | 110 | 100 | 90 }
参数
要修改的数据库的名称。
可以配置以下兼容级别值(并非所有版本都支持所有以上列出的兼容级别):
| Product | 数据库引擎版本 | 兼容级别指定 | 支持的兼容级别值 |
|---|---|---|---|
| SQL Server 2019 预览 | 15 | 150 | 150、140、130、120、110、100 |
| SQL Server 2017 (14.x) | 14 | 140 | 140、130、120、110、100 |
| 逻辑服务器 | 12 | 130 | 150、140、130、120、110、100 |
| 托管实例 | 12 | 130 | 150、140、130、120、110、100 |
| SQL Server 2016 (13.x) | 13 | 130 | 130、120、110、100 |
| SQL Server 2014 (12.x) | 12 | 120 | 120、110、100 |
| SQL Server 2012 (11.x) | 11 | 110 | 110、100、90 |
| SQL Server 2008 R2 | 10.5 | 100 | 100、90、80 |
| SQL Server 2008 | 10 | 100 | 100、90、80 |
| SQL Server 2005 | 9 | 90 | 90、80 |
| SQL Server 2000 | 8 | 80 | 80 |
备注
不过,强烈建议客户计划转到最新的兼容性级别,以便利用最新的改进。
ALTER DATABASE SCOPED CONFIGURATION (Transact-SQL),尤其是其关键字 LEGACY_CARDINALITY_ESTIMATION = ON。
Azure SQL Database。
数据库引擎的版本。
SELECT SERVERPROPERTY('ProductVersion');
备注
Azure SQL Database上并不支持所有功能(因兼容级别而异)。
sys.databases (Transact-SQL) 的 compatibility_level 列。
SELECT name, compatibility_level FROM sys.databases;
Remarks
这既适用于系统数据库也适用于用户数据库。
SQL Server 2017 (14.x) 应出现以下行为:
- 如果升级前用户数据库的兼容级别为 100 或更高,升级后将保持相应级别。
- SQL Server 2017 (14.x) 支持的最低兼容级别。
- 升级后,tempdb、model、msdb 和 Resource 数据库的兼容性级别将设置为当前兼容性级别。
- master 系统数据库保留它在升级之前的兼容性级别。
sys.databases 目录视图中的 compatibility_level 列。
备注
SQL Server 版本将导致分发数据库的兼容性级别增加到可与主数据库匹配。
兼容性级别和 SQL Server 升级
利用兼容性级别获得后向兼容性。
升级数据库兼容性级别的最佳做法。
提示
SQL Server 版本本机数据库兼容性级别上隐式测试和验证。
SQL Server 版本的数据库兼容性级别时,数据库兼容性级别可为现有应用程序提供简易的认证途径。
有关兼容性级别之间的差异的详细信息,请参阅后文相应的部分。
此处。
备注
SQL Server 2005 作为源版本。
重要
应该确定适用于自己的应用程序和场景的最小测试。
备注
Microsoft 在下列情况下提供查询计划形状保护:
- SQL Server 版本(源)运行的硬件上运行。
- 支持的数据库兼容性级别。
如果出现这种情况,请与 Microsoft 客户支持服务部门联系。
利用兼容性级别获得向后兼容
SQL Server 的早期版本保持部分后向兼容。
提示
SQL Server 数据库引擎 上运行但使用较旧的数据库兼容级别的应用程序仍可利用服务器级增强功能,无需对应用程序进行任何更改。
自动 Soft-NUMA。
升级数据库兼容性级别的最佳做法。
重要
SQL Server 数据库引擎中删除的功能。
SQL Server 2008 中废止的数据库引擎功能。
重要
但是,已更改或删除的系统对象不受兼容级别保护。
若要还原以前的转换行为,请将数据库兼容级别设置为 120 或更低。
兼容级别不保护的重大更改示例有:
- 无论兼容级别如何,查询
SELECT single_pages_kb FROM sys.dm_os_sys_info都会生成错误 207(列名无效)。 - 无论兼容级别如何,语句
EXEC sp_dboption 'AdventureWorks2016CTP3', 'autoshrink', 'FALSE';都会生成错误 2812(找不到存储过程“sp_dboption”)。
SQL Server 2008 中数据库引擎功能的重大更改。
升级数据库兼容性级别的最佳做法
更改数据库兼容性模式和使用查询存储。
兼容性级别和存储过程
在更改某一数据库的兼容性设置时,该数据库的所有存储过程都将随之自动重新编写。
兼容性级别 140 和 150 的区别
此部分介绍了随兼容性级别 150 一起引入的新行为。
除了数据库兼容性级别 140 中引入的改进之外,此数据库兼容性级别还将与下一代查询处理改进相关联。
SQL Server 2019 中的新增功能。
兼容级别 130 与兼容级别 140 之间的差异
本节介绍随兼容级别 140 引入的新行为。
| 兼容级别设置为 130 或更低 | 兼容级别设置为 140 |
|---|---|
| 引用多语句表值函数的语句的基数估计使用固定行猜测。 | 这通过多语句表值函数的交错执行来实现。 |
| 请求会导致溢出到磁盘的不充足内存授予大小的批处理模式查询可能会继续对连续执行产生问题。 | 这通过在对批处理模式运算符发生溢出时,会更新缓存计划内存授予大小的批处理模式内存授予反馈来实现。 |
| 请求会导致并发问题的过多内存授予大小的批处理模式查询可能会继续对连续执行产生问题。 | 这通过在最初请求了过多量时,会更新缓存计划内存授予大小的批处理模式内存授予反馈来实现。 |
| 如果发生这种情况,则性能会降低,并且不适当的联接算法会保持使用,直到缓存计划进行重新编译。 | 如果发生这种情况,并且语句有资格进行自适应联接,则会将嵌套循环用于较小联接输入,将哈希联接动态用于较大联接输入,而无需重新编译。 |
| 引用列存储索引的普通计划没有资格进行批处理模式执行。 | 引用列存储索引的普通计划会被放弃,以便支持有条件进行批处理模式执行的计划。 |
sp_execute_external_script UDX 运算符只能在行模式下运行。 |
sp_execute_external_script UDX 运算符有资格进行批处理模式执行。 |
| 多语句表值函数 (TVF) 没有交错执行 | 用于改进计划质量的多语句 TVF 交错执行。 |
跟踪标志 4199。
兼容级别 120 和兼容级别 130 之间的差异
本节介绍随兼容级别 130 引入的新行为。
| 兼容级别设置为 120 或更低 | 兼容级别设置为 130 |
|---|---|
| INSERT-SELECT 语句中的 INSERT 是单线程。 | INSERT-SELECT 语句中的 INSERT 是多线程,或者可以具有并行计划。 |
| 内存优化表的查询执行单线程。 | 内存优化表的查询现在可以具有并行计划。 |
列存储索引的批处理模式与行模式更改:
|
列存储索引的批处理模式与行模式更改:
|
| 可以自动更新统计信息。 | 在实践中,这应减少以下情况:对于经常查询新插入的行,但是未更新统计信息以包括这些值的查询,客户遇到性能问题。 |
| SQL Server 2014 (12.x) 中,跟踪 2371 默认情况下会关闭。 | 另一个改进是让查询在更新统计信息进程运行期间运行,而不阻塞查询。 |
| 对于级别 120,统计信息通过单线程进程进行采样。 | 对于级别 130,统计信息通过多线程进程进行采样。 |
| 253 传入外键是限制。 | Create Foreign Key Relationships。 |
| 允许使用弃用的 MD2、MD4、MD5、SHA 和 SHA1 哈希算法。 | 只允许使用 SHA2_256 和 SHA2_512 哈希算法。 |
| SQL Server 2016 improvements in handling some data types and uncommon operations(SQL Server 2016 在处理某些数据类型和不常见操作方面所做的改进)。 | |
| STRING_SPLIT 函数不可用。 | SQL Server 将无法找到并执行 STRING_SPLIT 函数。 |
跟踪标志 4199。
较低兼容性级别和级别 120 之间的差异
本节介绍随兼容性级别 120 引入的新行为。
| 兼容性级别设置为 110 或更低 | 兼容性级别设置为 120 |
|---|---|
| 使用旧版查询优化器。 | 数据库引擎中的新增功能主题的“查询计划”一节中的建议。 |
| 请参阅下面“示例”部分中的“示例 B”。 | 将 date 值转换为字符串值时,不忽略语言设置。 |
| 下面“示例”部分中的示例 C 演示此行为。 | EXCEPT 子句中的递归引用产生遵从 ANSI SQL 标准的错误。 |
| 递归公用表表达式 (CTE) 允许重复的列名。 | 递归 CTE 不允许列名重复。 |
| 如果更改触发器,则启用禁用的触发器。 | 更改触发器不更改触发器的状态(已启用或已禁用)。 |
OUTPUT INTO 表子句忽略 IDENTITY_INSERT SETTING = OFF,并允许插入显式值。 |
将 IDENTITY_INSERT 设置为 OFF 后,不能为表中的标识列插入显式值。 |
将数据库包含设置为部分包含后,验证 MERGE 语句的 OUTPUT 子句中的 $action 字段可能会返回排序规则错误。 |
MERGE 语句的 $action 子句返回的值的排序规则是数据库排序规则而非服务器排序规则,因此不会返回排序规则冲突错误。 |
SELECT INTO 语句始终创建单线程插入操作。 |
插入大量行时,并行操作可提高性能。 |
较低兼容性级别与级别 110 和 120 之间的差异
此部分也适用于级别 120。
| 兼容性级别设置为 100 或更低 | 至少为 110 的兼容性级别设置 |
|---|---|
| CLR 集成中的新增功能。 | CLR 数据库对象用 CLR 的版本 4 执行。 |
| XQuery 函数 string-length 和 substring 将每个代理项计为两个字符。 | XQuery 函数 string-length 和 substring 将每个代理项计为一个字符。 |
| 然而,当每个分组有多个行时,该查询返回不正确的结果。 | 将返回错误。 |
| SQL Server 2012 (11.x) 中,可以通过任何兼容性级别对使用 RC4 或 RC4_128 加密的材料进行解密。 | SQL Server 2012 (11.x) 中,可以通过任何兼容性级别对使用 RC4 或 RC4_128 加密的材料进行解密。 |
| CAST 和 CONVERT (Transact SQL)。 | 您需要手动更新此数据,以匹配样式 121。 |
| 本地表中相应的列(在选择列表中的相同序号位置中)必须为 datetime 类型。 | 可以通过将针对远程表的数据类型更改为 datetime 或者将本地数据库的兼容级别设置为 100 或更低,解决上述问题。 |
如果一组并行辅音具有相同的 SOUNDEX代码,则将不包含它们,第一个辅音除外。 |
SOUNDEX (Transact-SQL)。 |
兼容性级别 90 和兼容性级别 100 之间的差异
本节介绍随兼容性级别 100 引入的新行为。
| 兼容性级别设置为 90 | 兼容性级别设置为 100 | 影响的可能性 |
|---|---|---|
| 对于多语句表值函数,在创建它们时,无论会话级别设置如何,QUOTED_IDENTIFER 设置始终为 ON。 | 在创建多语句表值函数时,会遵循 QUOTED IDENTIFIER 会话设置。 | Medium |
| 在创建或更改分区函数时,会评估函数中的 datetime 和 smalldatetime 文字,并假定语言设置为 US_English。 | 使用当前语言设置来评估该分区函数中的 datetime 和 smalldatetime 文字。 | Medium |
允许在 INSERT 和 SELECT INTO 语句中使用(并忽略)FOR BROWSE 子句。 |
不允许在 INSERT 和 SELECT INTO 语句中使用 FOR BROWSE 子句。 |
Medium |
OUTPUT 子句中允许使用全文谓词。 |
OUTPUT 子句中不允许使用全文谓词。 |
Low |
| 系统非索引字表自动与新的全文检索相关联。 | CREATE FULLTEXT STOPLIST、ALTER FULLTEXT STOPLIST 和 DROP FULLTEXT STOPLIST 受支持。 |
Low |
MERGE 不作为保留关键字强制应用。 |
在 100 和 90 兼容级别下,都支持 MERGE 语句。 |
Low |
| 使用 INSERT 语句的 <dml_table_source> 参数会引发语法错误。 | 这通过使用 INSERT 语句的 <dml_table_source> 参数来实现。 | Low |
| 不支持空间索引。 | 如果还指定了 NOINDEX,则仅执行逻辑检查。 |
Low |
| 如果将 OUTPUT 子句和数据操作语言 (DML) 语句一起使用,并且在语句执行过程中发生运行时错误,则会终止并回滚整个事务。 | 如果 SET XACT_ABORT 设置为 ON,则由使用 OUTPUT 子句的 DML 语句所生成的全部运行时错误都将终止批处理,并回滚事务。 |
Low |
| CUBE 和 ROLLUP 不作为保留关键字强制应用。 | CUBE 和 ROLLUP 是 GROUP BY 子句中的保留关键字。 |
Low |
| 对 XML anyType 类型的元素应用严格验证。 | 通配符组成部分和内容验证。 | Low |
| 也是如此。 | 来替换 | Low |
| SQL Server datetime 类型的用户定义函数被标记为确定的。 | SQL Server datetime 类型的用户定义函数被标记为不确定的。 | Low |
| 不完全支持 XML 联合和列表类型。 | 联合的列表 | Low |
| 当视图或内联表值函数中包含 xQuery 方法时,不对该方法所需的 SET 选项进行验证。 | 如果该方法的 SET 选项设置不正确,将引发一个错误。 | Low |
| 即返回回车符和换行符,而不是单个换行符。 | 若要避免规范化过程,请使用 XML 数字字符实体对所有行尾字符进行编码。 | Low |
例如,CREATE TABLE T (C1 int CONSTRAINT MyConstraint IDENTITY)语句可以执行,但约束名不会保留,也无法让用户访问。 |
返回错误 156。 | Low |
| 只有在兼容性级别设置为 90 时,此行为才适用。 | 使用双向赋值来更新列会产生预期的结果,因为在语句执行过程中,只会访问列的语句起始值。 | Low |
| 请参阅下面“示例”部分中的“示例 E”。 | 请参阅下面“示例”部分中的“示例 F”。 | Low |
对于有些语言,默认格式为 YDM,这会导致在将 CONVERT() 与要求使用 YMD 格式的其他函数(如 {fn CURDATE()})结合使用时出现转换错误。 |
在转换为 ODBC 数据类型 SQL_TIMESTAMP、SQL_DATE、SQL_TIME、SQLDATE、SQL_TYPE_TIME 和 SQL_TYPE_TIMESTAMP 时,ODBC 函数 {fn CONVERT()} 使用样式 121(一种独立于语言的 YMD 格式)。 |
Low |
例如,SELECT DATEPART (year, '2007/05-30')会编译成功。 |
在使用无效的日期时间文字时,会返回错误 241。 | Low |
保留关键字
下表显示了每个兼容性级别所引入的保留关键字。
| 兼容性级别设置 | 保留关键字 |
|---|---|
| 130 | 待定。 |
| 120 | 无。 |
| 110 | WITHIN GROUP、TRY_CONVERT、SEMANTICKEYPHRASETABLE、SEMANTICSIMILARITYDETAILSTABLE、SEMANTICSIMILARITYTABLE |
| 100 | CUBE、MERGE、ROLLUP |
| 90 | EXTERNAL、PIVOT、UNPIVOT、REVERT、TABLESAMPLE |
在较低的兼容性级别中,级别 100 的关键字仍保留有效的对象名,但与这些关键字相对应的级别 110 的语言功能将不可用。
例如,在兼容性级别 90 中引入的保留关键字 PIVOT 在级别 100、110 和 120 中也被保留。
保留关键字 (Transact-SQL) 。
Permissions
需要对数据库拥有 ALTER 权限。
示例
更改兼容性级别
SQL Server 2012 (11.x)。
ALTER DATABASE AdventureWorks2012
SET COMPATIBILITY_LEVEL = 110;
GO
以下示例返回当前数据库的兼容级别。
SELECT name, compatibility_level
FROM sys.databases
WHERE name = db_name();
忽略 SET LANGUAGE 语句(除非低于兼容级别 120)
只有兼容级别低于 120 时,以下查询才会忽略 SET LANGUAGE 语句。
SET DATEFORMAT dmy;
DECLARE @t2 date = '12/5/2011' ;
SET LANGUAGE dutch;
SELECT CONVERT(varchar(11), @t2, 106);
-- Results when the compatibility level is less than 120.
12 May 2011
-- Results when the compatibility level is set to 120).
12 mei 2011
C.
对于 110 或更低的兼容级别设置,EXCEPT 子句右侧的递归引用产生无限循环。
WITH
cte AS (SELECT * FROM (VALUES (1),(2),(3)) v (a)),
r
AS (SELECT a FROM Table1
UNION ALL
(SELECT a FROM Table1 EXCEPT SELECT a FROM r) )
SELECT a
FROM r;
D.
CAST 和 CONVERT (Transact SQL)。
CREATE TABLE t1 (c1 time(7), c2 datetime2);
INSERT t1 (c1,c2) VALUES (GETDATE(), GETDATE());
SELECT CONVERT(nvarchar(16),c1,0) AS TimeStyle0
,CONVERT(nvarchar(16),c1,121)AS TimeStyle121
,CONVERT(nvarchar(32),c2,0) AS Datetime2Style0
,CONVERT(nvarchar(32),c2,121)AS Datetime2Style121
FROM t1;
-- Returns values such as the following.
TimeStyle0 TimeStyle121
Datetime2Style0 Datetime2Style121
---------------- ----------------
-------------------- --------------------------
3:15PM 15:15:35.8100000
Jun 7 2011 3:15PM 2011-06-07 15:15:35.8130000
E.
在这种情况下,会正确地将最后一个值赋给变量,但还会返回 SELECT UNION 语句的结果集。
ALTER DATABASE AdventureWorks2012
SET compatibility_level = 110;
GO
USE AdventureWorks2012;
GO
DECLARE @v int;
SELECT @v = BusinessEntityID FROM HumanResources.Employee
UNION ALL
SELECT @v = BusinessEntityID FROM HumanResources.EmployeeAddress;
SELECT @v;
F.
若要纠正该错误,请重写查询,如下例所示。
DECLARE @v int;
SELECT @v = BusinessEntityID FROM
(SELECT BusinessEntityID FROM HumanResources.Employee
UNION ALL
SELECT BusinessEntityID FROM HumanResources.EmployeeAddress) AS Test;
SELECT @v;
另请参阅
查看或更改数据库的兼容级别