一時テーブルが不要になったときに、カーソルを使用して一時テーブルをクリーンアップしようとしています。一時テーブルの名前と識別子を含む小さなテーブルがあります。カーソルは無限ループに陥っていますが、その中で特定のステートメントを実行した場合のみです。 FETCH
から値を出力するだけで、完全に機能します。これがコードです。
_DECLARE @id bigint;
DECLARE @table_name varchar(max);
DECLARE st CURSOR LOCAL FAST_FORWARD FOR
SELECT ID, TableName FROM SearchTables WHERE CustomerID IS NULL
OPEN st
FETCH NEXT FROM st INTO @id, @table_name
WHILE @@FETCH_STATUS <> -1
BEGIN
IF(OBJECT_ID(@table_name) IS NOT NULL)
EXEC('DROP TABLE ' + @table_name);
UPDATE SearchTables SET Deleted=1 WHERE ID=@id;
PRINT CAST(@id AS varchar(max)) + ' ' + @table_name;
FETCH NEXT FROM st INTO @id, @table_name;
END
CLOSE st
DEALLOCATE st
_
これらの行をコメントアウトすると
_ IF(OBJECT_ID(@table_name) IS NOT NULL)
EXEC('DROP TABLE ' + @table_name);
UPDATE SearchTables SET Deleted=1 WHERE ID=@id;
_
PRINT
は、すべてのIDとテーブル名を出力します。コメントしないと、クエリをキャンセルするまで、最初の行が何度も表示されます。また、IF
行をEXEC('DROP TABLE IF EXISTS ' + @table_name)
に変更してみましたが、それも機能しませんでした。
おそらく、Deleted=1
を設定してFAST_FORWARDカーソルで再度読み取るときに、行を移動しています。代わりにSTATICカーソルを使用してください。これにより、データのコピーが反復処理され、走査しているデータ構造の変更が回避されます。
DECLARE st CURSOR LOCAL STATIC FOR . . .
WHILE @@FETCH_STATUS = 0
が必要です。これは、何かが正しくない限り続行することを意味します。
<> -1
を使用すると、フェッチされた行が欠落していても、またはフェッチ操作を実行していなくても続行され、戻り値として-1
を取得しない限り、その戻り値は 4戻り値@@FETCH_STATUS
の場合。
0 The FETCH statement was successful.
-1 The FETCH statement failed or the row was beyond the result set.
-2 The row fetched is missing.
-9 The cursor is not performing a fetch operation
。