如何检测兼容性错误 - SQL Server 2012

Din*_*ina 6 sql-server-2008 sql-server-2012 compatibility-level

我正在将数据库的兼容模式从 90 (SQL Server 2005) 更改为 110 (SQL 2012),我想知道在什么时候我会看到中断更改导致的错误(如果有的话)。

我运行了 Upgrade Advisor 2012,它发现了几个需要更新的存储过程。一个例子是:

“在 SQL Server 2005 或更高版本中,ORDER BY 子句中的列别名不能以表别名为前缀。”

但是,当我在 SQL 2012 中运行这个存储过程(没有做任何更改)时,它没有显示任何错误。此外,当我将数据库兼容性级别从 90 更改为 110 时,也没有错误。当我恢复数据库时也没有。

如果我没有在任何地方看到错误,我希望升级顾问能捕获所有内容。还有其他方法可以检查兼容性错误吗?

此外,即使升级顾问告诉我它会失败,这个存储过程怎么可能成功运行?谢谢 :)

Aar*_*and 6

你能显示查询吗?仅仅因为它运行并不意味着它是正确的。:-) 例如,这是不合法的,但它有效:

SELECT CONVERT(SMALLDATETIME, modify_date) AS modify_date
FROM sys.objects AS o
ORDER BY o.modify_date;
Run Code Online (Sandbox Code Playgroud)

从技术上讲,它应该如下,因为o.modify_date不在SELECT列表中:

SELECT CONVERT(SMALLDATETIME, modify_date) AS modify_date
FROM sys.objects AS o
ORDER BY modify_date;
Run Code Online (Sandbox Code Playgroud)

这个 Connect bug 中,据说这条规则将从升级顾问中删除。我怀疑发生了以下其中一项(或两者):

  1. 他们忘记删除规则,因为他们说他们会
  2. 他们还有其他复杂情况,阻止了上述语法被解析器阻止

尽管如此,升级顾问永远无法捕捉到一些重大变化。例如,这将适用于 2005、2008 和 2008 R2:

CREATE TABLE #foo(id INT);

IF OBJECT_ID('tempdb..#foo') > 0
BEGIN
  DROP TABLE #foo;
END
GO

CREATE TABLE #foo(id INT);
Run Code Online (Sandbox Code Playgroud)

但是,这将在 SQL Server 2012 中中断,因为 #temp 表现在获得负的 object_id。正确的测试方法是:

IF OBJECT_ID('tempdb..#foo') IS NOT NULL
Run Code Online (Sandbox Code Playgroud)

我在这篇博文中讨论了其他一些问题。其他一些重大变化:

如果您使用任何与内存相关的 DMV,则对某些列进行了大修:

同样,其中大部分都不会被升级顾问捕获,因此运行该工具而不进行任何彻底的测试可能会让您陷入困境。

我同意Eric 的回答——您应该尝试跟踪已弃用的事件。为了完整起见,这里提供三种方法: