1

我有一个使用游标的存储过程;它是用 SQL Server 2005 编写的,在 SQL Server 2008 之前运行良好。

我们最近决定迁移到 SQL Server 2012,并尝试将我们所有的数据库迁移到新环境,但是这个存储过程在打开游标时失败。

这是部分:

BEGIN TRY
        SELECT @SqlStatement =  'DECLARE cursorMoveStatements  INSENSITIVE CURSOR  FOR ' 
                                + 'Select [name],[status] From  [' + @ServerName 
                                +'].['+ @DBName 
                                + '].sys.sysfiles FOR READ ONLY'
        EXEC sp_executesql @SqlStatement

            OPEN cursorMoveStatements
    ..... --Do Some Stuff
        END TRY

@ServerName并且@DBName更早地被适当地声明和设置。运行时,错误表明当我尝试打开它时未设置 cursorMoveStatements。

我知道我可以设置一个包含游标的变量,然后将其传递给 sp_executesql 并通过其 OUTPUT 关键字获取设置的游标,但这将迫使我重写该 SP 的大部分(这真的很长)。我想知道 SQL Server 中发生了什么变化导致这部分(在旧版本的 SQL 中运行良好)失败。我搜索了 MSDN,但找不到关于现在有什么不同的线索。

任何帮助,如果不是“修复”这个问题,至少让我了解 SQL Server 2012 中有什么不同之处导致它不起作用?

4

1 回答 1

1

您的答案可能在cursor name scope的文档中。具体而言,有关以下信息CURSOR_DEFAULT

如果未指定LOCALGLOBAL ,则使用ALTER DATABASE语句设置的数据库选项CURSOR_DEFAULT控制DECLARE CURSOR语句采用的默认值。

您的新 SQL Server 2012 数据库可能CURSOR_DEFAULT与您的 SQL Server 2005 数据库不同。

ALTER DATABASE SET OptionCURSOR_DEFAULT更详细地描述了如何工作:

CURSOR_DEFAULT { 本地 | GLOBAL }
控制游标范围是使用 LOCAL 还是 GLOBAL。

LOCAL
如果指定了 LOCAL 并且在创建游标时未将游标定义为 GLOBAL,则游标的范围对于创建游标的批处理、存储过程或触发器是本地的。游标名称仅在此范围内有效。游标可以被批处理、存储过程或触发器中的局部游标变量或存储过程的 OUTPUT 参数引用。当批处理、存储过程或触发器结束时,游标会被隐式释放,除非它在 ​​OUTPUT 参数中传回。如果游标在 OUTPUT 参数中传回,则当引用它的最后一个变量被释放或超出范围时,游标将被释放。

GLOBAL
When GLOBAL is specified, and a cursor is not defined as LOCAL when created, the scope of the cursor is global to the connection. The cursor name can be referenced in any stored procedure or batch executed by the connection.

于 2012-08-31T10:43:40.743 回答