SEa*_*986 4 sql-server-2008 cursors sql-server-2016 compatibility-level
我发现数据库兼容性级别之间的一段代码的行为存在差异,并想知道其原因是什么。下面是一个简单的示例,它迭代计数表并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
Run Code Online (Sandbox Code Playgroud)
受影响的代码:
/* 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
Run Code Online (Sandbox Code Playgroud)
如果我运行上面的代码,[100Compat]
它会在消息窗口中打印数字 1-100。
如果我针对 运行上面的命令[110Compat]
,[120Compat]
或者[130Compat]
我可以在消息窗口中看到值 1-50 和错误消息
消息 16958,级别 16,状态 3,第 41 行 无法完成游标操作,因为自声明游标以来设置的选项已更改。
导致这种行为变化的两种兼容性模式之间的差异是什么?是否有在 110 或类似的情况下启用/禁用的跟踪标志?
我看过这篇文章,但似乎没有什么明显的原因导致了这种差异
SQL Server 2012 引入了对 SET ROWCOUNT 的重大更改:
SET ROWCOUNT 的行为已更改,以提高许多常见查询的效率,并且可能影响兼容性级别 110 及更高级别的查询计划。当 SET ROWCOUNT 语句在 DECLARE CURSOR 语句之后和 FETCH 语句之前将 ROWCOUNT 值更改为 0 或从 0 开始时,可能会导致错误。要避免此错误,请将数据库兼容性级别设置为 100 或在游标语句之外设置 ROWCOUNT。
正如您的重现脚本所示,此更改由数据库兼容性级别控制。ROWCOUNT
声明游标后更改设置时,兼容级别 110 (SQL 2012) 或更高版本将导致错误。
归档时间: |
|
查看次数: |
472 次 |
最近记录: |