CURSOR 中的无限循环

CB_*_*Ron 6 t-sql cursors

我正在尝试使用游标来清理不再需要的临时表。我有一个小表,其中包含临时表的名称和标识符。游标陷入无限循环,但前提是我在其中执行某些语句。如果我只是打印出 中的值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
Run Code Online (Sandbox Code Playgroud)

如果我注释掉这些行

    IF(OBJECT_ID(@table_name) IS NOT NULL) 
        EXEC('DROP TABLE ' + @table_name);

    UPDATE SearchTables SET Deleted=1 WHERE ID=@id;
Run Code Online (Sandbox Code Playgroud)

PRINT输出所有的 ID 和表名。如果我不评论它们,我得到的只是一遍又一遍的第一行,直到我取消查询。我也尝试将IF线路更改为,EXEC('DROP TABLE IF EXISTS ' + @table_name)但这也不起作用。

Dav*_*oft 12

当您Deleted=1使用 FAST_FORWARD 游标设置并再次读取它时,您可能正在移动该行。改用 STATIC 游标,它将迭代数据的副本,并避免改变您正在遍历的数据结构。

DECLARE st CURSOR LOCAL STATIC FOR . . .
Run Code Online (Sandbox Code Playgroud)


scs*_*mon 9

你想要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
Run Code Online (Sandbox Code Playgroud)

.