web-dev-qa-db-fra.com

Boucle infinie dans CURSOR

J'essaie d'utiliser un curseur pour nettoyer les tables temporaires lorsqu'elles ne sont plus nécessaires. J'ai une petite table qui a les noms des tables temporaires avec un identifiant. Le curseur est coincé dans une boucle infinie, mais seulement si j'y exécute certaines instructions. Si je viens d'imprimer les valeurs du FETCH, cela fonctionne parfaitement. Voici le code.

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

Si je commente ces lignes

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

    UPDATE SearchTables SET Deleted=1 WHERE ID=@id;

PRINT renvoie tous les ID et noms de table. Si je ne les commente pas, tout ce que j'obtiens est la première ligne encore et encore jusqu'à ce que j'annule la requête. J'ai également essayé de changer la ligne IF en EXEC('DROP TABLE IF EXISTS ' + @table_name) mais cela n'a pas fonctionné non plus.

6
CB_Ron

Vous déplacez probablement la ligne lorsque vous définissez Deleted=1 et le relire avec votre curseur FAST_FORWARD. Utilisez plutôt un curseur STATIQUE, qui itérera une copie des données et évitera de muter la structure de données que vous parcourez.

DECLARE st CURSOR LOCAL STATIC FOR . . .
12

Tu veux WHILE @@FETCH_STATUS = 0 ce qui signifie continuer sauf si quelque chose ne va pas.

En utilisant <> -1 signifie qu'elle continuera même si la ligne récupérée était manquante, ou qu'elle n'exécute pas d'opération de récupération, la rendant infinie à moins que vous n'ayez -1 comme valeur de retour, car il y a 4 valeurs de retour pour @@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

.

9
scsimon