我发现数据库兼容性级别之间的一段代码的行为存在差异,并想知道这是什么原因。下面是一个简单的示例,它遍历一个计数表并ROWCOUNT
在第 50 次迭代时更改选项:
设置:
/* Create tally table */
SELECT TOP 100
ROW_NUMBER() OVER (ORDER BY a.object_id) AS Number
INTO #Tally
FROM sys.objects a
CROSS JOIN sys.objects b;
/* Create Some databases with different compatibility levels */
CREATE DATABASE [100Compat] WITH COMPATIBILITY_LEVEL = 100
CREATE DATABASE [110Compat] WITH COMPATIBILITY_LEVEL = 110
CREATE DATABASE [120Compat] WITH COMPATIBILITY_LEVEL = 120
CREATE DATABASE [130Compat] WITH COMPATIBILITY_LEVEL = 130
受影响的代码:
/* cursor through the tally table */
DECLARE MyCursor CURSOR
FOR
SELECT Number
FROM #Tally
FOR READ ONLY;
DECLARE @num INT;
OPEN MyCursor
FETCH MyCursor
INTO @num
WHILE @@FETCH_STATUS = 0
BEGIN
SET ROWCOUNT 0
/* change the value for ROWCOUNT on iteration 50 */
IF @num = 50 SET ROWCOUNT 1
PRINT @num
FETCH MyCursor
INTO @num
END
SET ROWCOUNT 0
CLOSE MyCursor
DEALLOCATE MyCursor
如果我对它运行上述内容,[100Compat]
则会在消息窗口中打印数字 1-100。
如果我针对 运行上述操作[110Compat]
,[120Compat]
或者[130Compat]
我可以在消息窗口中看到值 1-50 和错误消息
消息 16958,级别 16,状态 3,第 41 行无法完成游标操作,因为自声明游标后设置选项已更改。
导致这种行为变化的两种兼容模式之间有什么区别?是否有在 110 中启用/禁用的跟踪标志或类似的东西?
我看过这篇文章,但似乎没有什么明显的原因导致差异
SQL Server 2012对 SET ROWCOUNT 进行了重大更改:
正如您的重现脚本所演示的,此更改由数据库兼容性级别控制。
ROWCOUNT
在声明游标后更改设置时,兼容级别 110 (SQL 2012) 或更高版本将导致错误。