Estou tentando usar um cursor para limpar tabelas temporárias quando elas não forem mais necessárias. Eu tenho uma pequena tabela que tem os nomes das tabelas temporárias junto com um identificador. O cursor está preso em um loop infinito, mas somente se eu executar certas instruções nele. Se eu apenas imprimir os valores do FETCH
, funciona perfeitamente. Aqui está o código.
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
Se eu comentar essas linhas
IF(OBJECT_ID(@table_name) IS NOT NULL)
EXEC('DROP TABLE ' + @table_name);
UPDATE SearchTables SET Deleted=1 WHERE ID=@id;
PRINT
gera todos os IDs e nomes de tabela. Se eu não comentá-los, tudo o que recebo é a primeira linha repetidamente até cancelar a consulta. Eu também tentei mudar a IF
linha para, EXEC('DROP TABLE IF EXISTS ' + @table_name)
mas isso também não funcionou.
Provavelmente você está movendo a linha ao definir
Deleted=1
e lendo-a novamente com o cursor FAST_FORWARD. Em vez disso, use um cursor STATIC, que irá iterar uma cópia dos dados e evitar a mutação da estrutura de dados que você está percorrendo.Você quer
WHILE @@FETCH_STATUS = 0
o que significa continuar, a menos que algo não esteja certo.Usar
<> -1
significa que continuará mesmo se a linha buscada estiver ausente ou não estiver executando uma operação de busca, tornando-a infinita, a menos que você obtenha-1
um valor de retorno, pois existem 4 valores de retorno para@@FETCH_STATUS
..