SQL Server 2012 中数据库引擎功能的重大更改
本主题介绍 SQL Server 2012 数据库引擎和 SQL Server 早期版本中的重大更改。 这些更改可能导致基于 SQL Server 的早期版本的应用程序、脚本或功能无法继续使用。 在进行升级时可能会遇到这些问题。 有关详细信息,请参阅使用升级顾问来准备升级。
本主题内容
SQL Server 2012 中的重大更改
SQL Server 2008/SQL Server 2008 R2 中的重大更改
SQL Server 2005 中的重大更改
SQL Server 2012 中的重大更改
Transact-SQL
功能 |
说明 |
---|---|
从名为 NEXT 的列或表中进行选择 |
序列使用 ANSI 标准 NEXT VALUE FOR 函数。 如果表或列名为 NEXT 且该表或列的别名为 VALUE,在省略 ANSI 标准 AS 的情况下,所得到的语句可能会导致错误。 若要解决这个问题,请包括 ANSI 标准 AS 关键字。 例如,SELECT NEXT VALUE FROM Table 应被重写为 SELECT NEXT AS VALUE FROM Table,SELECT Col1 FROM NEXT VALUE 应被重写为 SELECT Col1 FROM NEXT AS VALUE。 |
PIVOT 运算符 |
当数据库兼容级别设置为 110 时,不允许在递归公用表表达式 (CTE) 查询中使用 PIVOT 运算符。 重写该查询,或将兼容级别设置为 100 或更低。 当每个分组有多个行时,在递归 CTE 查询中使用 PIVOT 会产生不正确的结果。 |
sp_setapprole 和 sp_unsetapprole |
sp_setapprole 的 cookie OUTPUT 参数当前记载为 varbinary(8000),这是正确的最大长度。 但是,当前实现返回 varbinary(50)。 应用程序应继续保留 varbinary(8000),以便当 cookie 在将来的版本中返回大小增量时,应用程序可继续正确运行。 有关详细信息,请参阅sp_setapprole (Transact-SQL)。 |
EXECUTE AS |
EXECUTE AS 的 cookie OUTPUT 参数当前记载为 varbinary(8000),这是正确的最大长度。 但是,当前实现返回 varbinary(100)。 应用程序应继续保留 varbinary(8000),以便当 cookie 在将来的版本中返回大小增量时,应用程序可继续正确运行。 有关详细信息,请参阅EXECUTE AS (Transact-SQL)。 |
sys.fn_get_audit_file 函数 |
添加了两个新列(user_defined_event_id 和 user_defined_information)来支持用户定义的审核事件。 不按名称选择列的应用程序可能会返回比预期更多的列。 请按名称选择列,或调整应用程序以接受这些额外的列。 |
对类型为 time 或 datetime2 的计算列执行 CAST 和 CONVERT 操作 |
在 SQL Server 的早期版本中,对 time 或 datetime2 数据类型的 CAST 和 CONVERT 操作的默认样式为 121,当在计算列表达式中使用这些类型时除外。 对于计算列,默认样式为 0。 当创建用于涉及自动参数化的查询中或约束定义中的计算列时,此行为会影响计算列。 兼容级别为 110 时,对 time 和 datetime2 数据类型的 CAST 和 CONVERT 操作的默认样式始终为 121。 如果您的查询依赖旧行为,请使用低于 110 的兼容级别或在受影响的查询中显式指定 0 样式。 将数据库升级到兼容级别 110 将不更改已存储到磁盘的用户数据。 您必须相应手动更正此数据。 例如,如果您使用了 SELECT INTO 来从包含上述计算列表达式的源创建表,将存储数据(使用样式 0)而非存储计算列定义本身。 您需要手动更新此数据,以匹配样式 121。 |
ALTER TABLE |
ALTER TABLE 语句只允许两部分的表名称 (schema.object)。 使用以下格式指定表名时,现在在编译时会失败,出现错误 117。
在早期版本中指定格式 server.database.schema.table 会返回错误 4902。 指定格式 .database.schema.table 或 ..schema.table 则会成功。 要解决此问题,请不要使用 4 部分的前缀。 |
浏览元数据 |
使用 FOR BROWSE 或 SET NO_BROWSETABLE ON 查询视图时,现在会返回视图的元数据而非基础对象的元数据。 此行为现在匹配浏览元数据的其他方法。 |
SOUNDEX |
数据库兼容级别为 110 时,SOUNDEX 函数实现的新规则可能导致由该函数计算的值不同于更低数据库兼容级别下计算的值。 在升级到兼容级别 110 后,可能需要重新生成使用 SOUNDEX 函数的索引、堆或 CHECK 约束。 有关详细信息,请参阅SOUNDEX (Transact-SQL)。 |
失败的 DML 语句的行计数消息 |
在 SQL Server 2012 中,DML 语句失败时,数据库引擎 将以一致方式将包含 RowCount:0 的 TDS DONE 令牌发送到客户端。 在 SQL Server 的早期版本中,当 TRY-CATCH 块包含失败的 DML 语句并且该语句由数据库引擎自动参数化或 TRY-CATCH 块所处的级别不同于失败语句的级别时,会向客户端发送不正确的值 -1。 例如,如果 TRY-CATCH 块调用存储过程且该过程中的 DML 语句失败,客户端将错误地收到 -1 值。 依赖这种不正确行为的应用程序将失败。 |
SERVERPROPERTY (‘Edition’) |
所安装的 SQL Server 2012 实例的产品版本。 使用该属性的值确定已安装的产品支持的功能和限制(如最大 CPU 数)。 基于安装的 Enterprise 版本,它可能返回“Enterprise Edition”或“Enterprise Edition:基于内核的许可”。 根据单个 SQL Server 实例的最大计算能力来区分 Enterprise 版本。 有关 SQL Server 2012 中计算能力限制的详细信息,请参阅按 SQL Server 版本划分的计算能力限制。 |
CREATE LOGIN |
CREATE LOGIN WITH PASSWORD = 'password' HASHED 选项不能用于 SQL Server 7 或更早版本创建的哈希。 |
针对 datetimeoffset 的 CAST 和 CONVERT 运算 |
在从日期和时间类型转换为 datetimeoffset 时支持的唯一样式是 0 或 1。 所有其他转换样式均返回错误 9809。 例如,下面的代码将返回错误 9809。
|
SET ROWCOUNT |
SET ROWCOUNT 的行为变成提高很多常用查询的效率并且能够影响 110 和更高兼容性级别的查询计划。 当 SET ROWCOUNT 语句将 ROWCOUNT 值更改为 0 或在 DECLARE CURSOR 语句后和在 FETCH 语句前从 0 更改时,会引发错误。 要避免该错误,请将数据库兼容性级别设置为 100 或将 ROWCOUNT 设置为游标语句之外。 |
动态管理视图
查看 |
说明 |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
sys.dm_exec_requests |
该命令列从 nvarchar(16) 更改为 nvarchar(32)。 |
||||||||||||
sys.dm_os_memory_cache_counters |
以下列已重命名。
|
||||||||||||
sys.dm_os_memory_cache_entries |
列 pages_allocated_count 已重命名为 pages_kb。 |
||||||||||||
sys.dm_os_memory_clerks |
列 multi_pages_kb 已删除。 列 single_pages_kb 已重命名为 pages_kb。 |
||||||||||||
sys.dm_os_memory_nodes |
以下列已重命名。
|
||||||||||||
sys.dm_os_memory_objects |
以下列已重命名。
|
||||||||||||
sys.dm_os_sys_info |
以下列已重命名。
|
||||||||||||
sys.dm_os_workers |
区域设置列已删除。 |
目录视图
查看 |
说明 |
---|---|
sys.data_spaces sys.partition_schemes sys.filegroups sys.partition_functions |
已将新列 is_system 添加到 sys.data_spaces 和 sys.partition_functions。 (sys.partition_schemes 和 sys.filegroups 将继承 sys.data_spaces 的列。) 此列中的值 1 指示该对象用于全文索引片段。 在 sys.partition_functions、sys.partition_schemes 和 sys.filegroups 中,新列不是最后一列。 请修改依赖于从这些目录视图中返回的列顺序的现有查询。 |
SQL CLR 数据类型(geometry、geography 和 hierarchyid)
包含空间数据类型和 hierarchyid 类型的程序集 Microsoft.SqlServer.Types.dll 已从版本 10.0 升级到版本 11.0。 满足以下条件时,引用此程序集的自定义应用程序可能失败:
将自定义应用程序从安装了 SQL Server 2008 R2 的计算机移到仅安装了 SQL Server 2012 的计算机时,由于引用的 SqlTypes 程序集的版本 10.0 不存在,应用程序将失败。 你可能会看到此错误消息:“Could not load file or assembly 'Microsoft.SqlServer.Types, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' or one of its dependencies. The system cannot find the file specified.”
当引用 SqlTypes 程序集版本 11.0 且也安装了版本 10.0 时,您可能会看到此错误消息:“System.InvalidCastException: Unable to cast object of type 'Microsoft.SqlServer.Types.SqlGeometry' to type 'Microsoft.SqlServer.Types.SqlGeometry'.”
当从针对 .NET 3.5、4 或 4.5 的自定义应用程序引用 SqlTypes 程序集版本 11.0 时,由于 SqlClient 按设计加载程序集的版本 10.0,该应用程序将失败。 当应用程序调用以下方法之一时,将出现此失败:
SqlDataReader 类的 GetValue 方法
SqlDataReader 类的 GetValues 方法
SqlDataReader 类的方括号索引运算符 []
SqlCommand 类的 ExecuteScalar 方法
您可以使用以下方法之一来解决此问题:
您可以通过调用 GetSqlBytes 方法替代以上所列的 Get 方法来检索 CLR SQL Server 系统类型,在您的代码中解决此问题,如以下示例中所示:
string query = "SELECT [SpatialColumn] FROM [SpatialTable]"; using (SqlConnection conn = new SqlConnection("...")) { SqlCommand cmd = new SqlCommand(query, conn); conn.Open(); SqlDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { // In version 11.0 only SqlGeometry g = SqlGeometry.Deserialize(reader.GetSqlBytes(0)); // In version 10.0 or 11.0 SqlGeometry g2 = new SqlGeometry(); g.Read(new BinaryReader(reader.GetSqlBytes(0).Stream)); } }
您可以通过在应用程序配置文件中使用程序集重定向来解决此问题,如以下示例中所示:
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> ... <dependentAssembly> <assemblyIdentity name="Microsoft.SqlServer.Types" publicKeyToken="89845dcd8080cc91" culture="neutral" /> <bindingRedirect oldVersion="10.0.0.0" newVersion="11.0.0.0" /> </dependentAssembly> ... </assemblyBinding> <runtime>
您可以通过为“类型系统版本”属性指定值“SQL Server 2012”以强制 SqlClient 加载程序集的版本 11.0,解决此问题。 此连接字符串属性仅在 .NET 4.5 和更高版本中使用。
assemblyBinding 标记必须包装在 runtime 标记下。
对 AWE 的支持
32 位地址窗口化扩展插件 (AWE) 已不受支持。 这可能会导致在 32 位操作系统上性能下降。 对于占用大量内存的安装,请迁移到 64 位操作系统。
XQuery 函数可识别代理项
XQuery 函数和运算符的 W3C 建议要求它们对代理项对进行计数,该代理项对用 UTF-16 编码将大范围 Unicode 字符表示单个符号。 但是,在 SQL Server 2012 之前的 SQL Server 版本中,字符串函数不能将代理对识别为单个字符。 某些字符串操作(例如,字符串长度计算和子字符串提取)会返回不正确的结果。 SQL Server 2012 现在完全支持 UTF-16,可正确处理代理项对。
SQL Server 中的 XML 数据类型只允许格式正确的代理项对。 但在某些情况下,一些函数仍会返回未定义的结果或意外结果,这是因为可能会将无效的或部分代理项对作为字符串值传递给 XQuery 函数。 在 SQL Server 中使用 XQuery 时,请考虑以下生成字符串值的方法:
提供常量字符串值作为二进制值。 在使用此方法时,仍可能传递无效的或部分代理项对。
通过提供字符实体来提供常量字符串值。 使用此方法时,仍可能传递无效或不完整代理对。 XQuery 函数需要高级字符的单字符实体。 如果提供代理项对字符的字符实体,这些函数将引发错误。
通过使用 sql:column 或 sql:variable 导入外部值。 在使用这些方法时,仍可能引入无效的或部分代理项对。
受影响的 XQuery 函数和运算符
以下 XQuery 函数和运算符现在可在 SQL Server 2012 中正确处理 UTF-16 代理项对:
fn:string-length。 但是,如果将无效或不完整代理对作为参数传递,则 string-length 的行为未定义。
fn:substring。
fn:contains。 但是,如果将部分代理项对作为值传递,则 contains 可能会返回意外结果,因为它可能会找到格式正确的代理项对中包含的部分代理项对。
fn:concat。 但是,如果将部分代理项对作为值传递,则 concat 会生成不正确的代理项对或部分代理项对。
比较运算符和 order by 子句。 比较运算符包括 +、<、>、<=、>=、eq、lt、gt、le 和 ge。
对系统过程的分布式查询调用
在从一个 服务器对另一个服务器进行调用时,通过 OPENQUERY 对某些系统过程进行的分布式查询调用将失败。 在 数据库引擎 无法发现某个过程的元数据时将出现此情况。 例如,SELECT * FROM OPENQUERY(..., 'EXEC xp_loginfo')。
向后兼容性
新行为取决于兼容级别
仅当数据库兼容级别为 110 或更高时,以下函数和运算符才具有上述新行为:
fn:contains。
fn:concat。
比较运算符和 order by 子句
新行为取决于函数的默认命名空间 URI
仅当默认命名空间 URI 对应于最终建议中的命名空间(即 http://www.w3.org/2005/xpath-functions)时,以下函数才具有上述新行为。 数据库兼容级别为 110 或更高时,默认情况下 SQL Server 2012 将默认函数命名空间绑定到此命名空间。 但是,无论兼容级别如何,使用此命名空间时,这些函数都将具有新行为。
fn:string-length
fn:substring
返回页首
SQL Server 2008/SQL Server 2008 R2 中的重大更改
本节包含 SQL Server 2008 中引入的重大更改。 SQL Server 2008 R2 中未引入任何更改。
排序规则
功能 |
说明 |
---|---|
新排序规则 |
SQL Server 2008 引入了新的排序规则,这些规则完全符合 Windows Server 2008 提供的排序规则。 这 80 个新排序规则以 *_100 版本引用表示,它们的语言准确性得到了改善。 如果为服务器或数据库选择新排序规则,请注意,具有旧客户端驱动程序的客户端可能无法识别新排序规则。 未被识别的排序规则可能会导致应用程序返回错误并失败。 请考虑以下解决方案:
|
公共语言运行时 (CLR)
功能 |
说明 |
---|---|
CLR 程序集 |
当数据库升级到 SQL Server 2008 后,将自动安装 Microsoft.SqlServer.Types 程序集以支持新数据类型。 升级顾问规则将检测存在名称冲突的任何用户类型或程序集。 升级顾问将建议您重命名所有冲突的程序集,并重命名所有冲突的类型或在代码中使用由两部分组成的名称来引用该预先存在的用户类型。 如果数据库升级检测到某个用户程序集具有冲突名称,它将自动重命名该程序集,并将数据库置于可疑模式下。 如果在升级过程中存在具有冲突名称的用户类型,则不会采取特殊步骤。 升级后,旧的用户类型和新的系统类型将同时存在。 用户类型将只能通过由两部分组成的名称使用。 |
CLR 程序集 |
SQL Server 2008 会安装 .NET Framework 3.5 SP1,以更新全局程序集缓存 (GAC) 中的库。 如果在 SQL Server 数据库中注册了不支持的库,则在升级到 SQL Server 2008 后,SQL Server 应用程序可能会停止工作。 这是因为,在 GAC 中为库提供服务或升级库时并不会更新 SQL Server 中的程序集。 如果某一程序集存在于 SQL Server 数据库和 GAC 中,该程序集的两个副本必须完全匹配。 否则,当 SQL Server CLR 集成使用该程序集时,将发生错误。 有关详细信息,请参阅支持的 .NET Framework 库。 升级数据库之后,请使用 ALTER ASSEMBLY 语句对该程序集在 SQL Server 数据库中的副本提供服务或进行升级。 有关详细信息,请参阅知识库文章 949080。 若要检测是否在应用程序中使用了任何不支持的 .NET Framework 库,请在数据库中运行以下查询。
|
CLR 例程 |
在 CLR 用户定义函数、用户定义聚合或用户定义类型 (UDT) 内使用模拟可导致应用程序在升级到 SQL Server 2008 后因出现错误 6522 而失败。 下列情况在 SQL Server 2005 中成功,而在 SQL Server 2008 中则失败。 针对每种情况提供了相应的解决方案。
|
动态管理视图
查看 |
说明 |
---|---|
sys.dm_os_sys_info |
删除了 cpu_ticks_in_ms 和 sqlserver_start_time_cpu_ticks列。 |
sys.dm_exec_query_resource_semaphores sys.dm_exec_query_memory_grants |
在 SQL Server 2008 中,resource_semaphore_id 列不是唯一 ID。 此更改会对故障排除查询执行造成影响。 有关详细信息,请参阅sys.dm_exec_query_resource_semaphores (Transact-SQL)。 |
错误和事件
功能 |
说明 |
---|---|
登录错误 |
在 SQL Server 2005 中,当使用 SQL 登录名连接到配置为仅使用 Windows 身份验证的服务器时,会返回错误 18452。 在 SQL Server 2008 中,则会返回错误 18456。 |
显示计划
功能 |
说明 |
---|---|
显示计划 XML 架构 |
向显示计划 XML 架构中添加了一个新的 SeekPredicateNew 元素,并且将封闭 xsd 序列 (SqlPredicatesType) 转换成了 <xsd:choice> 项。 现在,显示计划 XML 架构中可能会显示一个或多个 SeekPredicateNew 元素,而不再显示一个或多个 SeekPredicate 元素。 这两种元素是相互排斥的。 在显示计划 XML 架构中维护 SeekPredicate 的目的在于实现向后兼容;但是,在 SQL Server 2008 中创建的查询计划中也可以包含 SeekPredicateNew 元素。 如果不存在 SeekPredicate 元素,则预计从节点 ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple/QueryPlan/RelOp/IndexScan/SeekPredicates 仅检索 SeekPredicate 子元素的应用程序可能会失败。 可以重新编写该应用程序,使此节点中包含 SeekPredicate 或 SeekPredicateNew 元素。 有关详细信息,请参阅。 |
显示计划 XML 架构 |
向显示计划 XML 架构的 ObjectType 复杂类型中添加了一个新的 IndexKind 属性。 根据 SQL Server 2005 架构严格验证 SQL Server 计划的应用程序将失败。 |
Transact-SQL
功能 |
说明 |
||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
ALTER_AUTHORIZATION_DATABASE DDL 事件 |
在 SQL Server 2005 中,如果数据定义语言 (DDL) 操作中安全对象的实体类型为对象,则触发 DDL 事件 ALTER_AUTHORIZATION_DATABASE 后,会在 EVENTDATA xml 的 ObjectType 元素中返回值“object”。 在 SQL Server 2008 中,则返回实际类型(例如,“table”或“function”)。 |
||||||||||
CONVERT |
如果传递到 CONVERT 函数的样式无效,则会在二进制转换为字符或字符转换为二进制时,返回一个错误。 在早期版本的 SQL Server 中,该无效样式会设置为二进制与字符间相互转换时的默认样式。 |
||||||||||
对程序集 GRANT/DENY/REVOKE EXECUTE |
不能对程序集授予、拒绝或撤消“EXECUTE”权限。 此权限不起任何作用,并且现在会导致一个错误。 可以对引用程序集方法的存储过程或函数授予、拒绝或撤消“EXECUTE”权限。 |
||||||||||
对系统类型 GRANT/DENY/REVOKE 权限 |
不能对系统类型授予、拒绝或撤消权限。 在早期版本的 SQL Server 中,这些语句会成功,但是不起任何作用。 在 SQL Server 2008 中,则会返回错误。 |
||||||||||
GROUP BY |
GROUP BY 子句在用于分组依据列表的表达式中不能包含子查询。 在早期版本的 SQL Server 中,允许这样做。 在 SQL Server 2008 中,则会返回错误 144。 例如,以下代码在 SQL Server 2005 中运行成功而在 SQL Server 2008 中运行失败:
|
||||||||||
OUTPUT 子句 |
为了防止出现不确定的行为,当某个列是通过下列方法之一定义时,OUTPUT 子句不能通过视图或内联表值函数引用该列:
如果 SQL Server 在 OUTPUT 子句中检测到这样的列,将引发错误 4186。 有关详细信息,请参阅MSSQLSERVER_4186。 |
||||||||||
OUTPUT INTO 子句 |
OUTPUT INTO 子句的目标表不能有任何已启用的触发器。 |
||||||||||
precompute rank 服务器级选项 |
SQL Server 2008 不支持此选项。 请尽快修改当前使用此功能的应用程序。 |
||||||||||
READPAST 表提示 |
您不能在快照隔离下指定 READPAST 提示。 在将 READ_COMMITED_SNAPSHOT 或 ALLOW_SNAPSHOT_ISOLATION 数据库选项设置为 ON 时,将忽略 READPAST 提示。 但是,如果您将 READPAST 提示与 READCOMMITTEDLOCK 相结合,则 READPAST 行为与阻止 READCOMMITTED 提示等效。 |
||||||||||
sp_helpuser |
在 sp_helpuser 存储过程的结果集中返回的以下列名发生了更改。
|
||||||||||
透明数据加密 |
在 I/O 级别执行透明数据加密 (TDE):页结构在内存中不加密,而仅在将页写入到磁盘后才对页结构进行加密。 数据库文件和日志文件均加密。 当数据库使用 TDE 时,那些跳过常规 SQL Server 机制来访问页面(例如,通过直接扫描数据或日志文件)的第三方应用程序将失败,因为文件中的数据已被加密。 此类应用程序可以利用 Windows 加密 API 来开发用来在 SQL Server 外部对数据进行解密的解决方案。 |
XQuery
功能 |
说明 |
---|---|
Datetime 支持 |
在 SQL Server 2005 中,数据类型 xs:time、xs:date 和 xs:dateTime 不支持时区。 时区数据会映射到 UTC 时区。 SQL Server 2008 提供了符合标准的行为,从而导致了以下变化:
可以修改应用程序和 XQuery 表达式来利用新类型值。 |
XQuery 和 Xpath 表达式 |
在 SQL Server 2005中,XQuery 或 XPath 表达式中允许使用以冒号(“:”)开头的步骤。 例如,下面的语句在路径表达式中包含以冒号开头的名称测试 (CTR02)。
在 SQL Server 2008 中,这种用法是不允许的,因为它不符合 XML 标准。 返回错误 9341。 请删除前导冒号或为名称测试指定一个前缀,例如 (n$/CTR02) 或 (n$/p1:CTR02)。 |
Connecting
功能 |
说明 |
---|---|
使用 SSL 从 SQL Server Native Client 进行连接 |
当使用 SQL Server Native Client 进行连接时,将 "SERVER=shortname; FORCE ENCRYPTION=true" 用于其主题指定完全限定域名 (FQDN) 的证书的应用程序在过去由于放宽的验证而已进行了连接。 SQL Server 2008 R2 通过为证书实现 FQDN 主题增强安全性。 依赖于已放宽验证的应用程序必须采取以下措施之一:
|
返回页首
SQL Server 2005 中的重大更改
有关 SQL Server 2005 中引入的重大更改的列表,请参阅 SQL Server 2005 中数据库引擎功能的重大更改。
请参阅
参考
SQL Server 2012 中不推荐使用的数据库引擎功能
ALTER DATABASE 兼容级别 (Transact-SQL)