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 では問題なく動作する) が失敗する原因は、SQL Server の何が変わったのだろうか。MSDN を検索しましたが、現在何が違うのかについての手がかりが見つかりませんでした。

これを「修正」しない場合でも、少なくとも SQL Server 2012 でこれが機能しない原因の違いを理解できるようにするために、何か助けはありますか?

4

1 に答える 1

1

あなたの答えは、cursor name scopeのドキュメントにあるかもしれません。具体的には、以下に関する情報CURSOR_DEFAULT:

ALTER DATABASEステートメントで設定されたデータベース オプションCURSOR_DEFAULTは、 LOCALGLOBALも指定されていない場合にDECLARE CURSORステートメントで使用されるデフォルトを制御します。

新しい SQL Server 2012 データベースは、おそらくCURSOR_DEFAULTSQL Server 2005 データベースとは異なります。

ALTER DATABASE SET Optionより詳細にどのようCURSOR_DEFAULTに動作するかを説明します:

CURSOR_DEFAULT { ローカル | GLOBAL }
カーソル スコープで LOCAL と GLOBAL のどちらを使用するかを制御します。

LOCAL
LOCAL が指定され、作成時にカーソルが GLOBAL として定義されていない場合、カーソルの有効範囲は、カーソルが作成されたバッチ、ストアド プロシージャ、またはトリガーに対してローカルです。カーソル名は、このスコープ内でのみ有効です。カーソルは、バッチ、ストアド プロシージャ、またはトリガー内のローカル カーソル変数、またはストアド プロシージャの OUTPUT パラメータによって参照できます。カーソルは、バッチ、ストアド プロシージャ、またはトリガーが終了すると、暗黙的に割り当て解除されます (OUTPUT パラメーターで戻された場合を除く)。カーソルが OUTPUT パラメーターで返された場合、カーソルは、それを参照する最後の変数が割り当て解除されるかスコープ外になると、割り当て解除されます。

GLOBAL
GLOBAL が指定され、作成時にカーソルが LOCAL として定義されていない場合、カーソルの有効範囲は接続に対してグローバルです。カーソル名は、接続によって実行される任意のストアド プロシージャまたはバッチで参照できます。

于 2012-08-31T10:43:40.743 に答える