Как я могу сбросить переменную @@ FETCH_STATUS или установить ее в 0 в хранимой процедуре?
Кроме того, можно ли привязать FETCH_STATUS к определенному курсору?


Вы можете сбросить его, прочитав курсор, который находится не в конце таблицы.
Еще один связанный с этим вопрос, который у меня есть, - можно ли привязать FETCH_STATUS к определенному курсору?
Вы не можете:
@@FETCH_STATUS (Transact-SQL)
Returns the status of the last cursor FETCH statement issued against any cursor currently opened by the connection.
Так что в основном он не привязан ни к какому курсору.
Как писал Скливвз, нельзя.
Но мне интересно, почему вы хотите его сбросить?
В чем настоящая проблема?
Обычно у вас есть @@ FETCH_STATUS немедленно после FETCH, так зачем вам его сбрасывать?
Попытайтесь сохранить его результат во временной переменной, если вы не оцените сразу.
Если вы хотите сломать курсор, вы можете использовать ПЕРЕРЫВ
Но это только замена функции с 0 на 1.
fetch next
While @@fetch_Status = 0
begin
if (my condition)
break
fetch next ;
end
Вам нужно закрыть курсор, а затем снова открыть курсор.
DECLARE @IDs int
DECLARE MyCursor CURSOR FOR(SELECT ID FROM Table)
OPEN MyCursor
FETCH NEXT FROM MyCursor INTO @IDs
WHILE @@FETCH_STATUS=0
BEGIN
--Do your work(First loop)
FETCH NEXT FROM MyCursor INTO @IDs
END
CLOSE MyCursor
--Run the cursor again
OPEN MyCursor
FETCH NEXT FROM MyCursorINTO @IDs
WHILE @@FETCH_STATUS=0
BEGIN
--Other work (Second loop)
FETCH NEXT FROM MyCursor INTO @IDs
END
CLOSE MyCursor
DEALLOCATE MyCursor
У меня было то, что я считал необходимостью сбросить курсор. Я проводил некоторое тестирование с курсорами и возвращался с @@ fetch_status, равным -1, даже после того, как я закодировал закрытие и освобождение курсора, который я тестировал.
Произошло то, что я открыл глобальный курсор в другой процедуре после логической проверки и никогда не закрыл этот курсор после итерации по нему.
Итак, Fetch видел @@ Fetch_status этого курсора.
Закройте курсоры, освободите курсоры.
Я могу воспроизвести проблему @@FETCH_STATUS, которую вы описываете, это когда вы DECLARE на CURSOR и перебираете строки, вызывая FETCH NEXT, пока не получите @@FETCH_STATUS = -1.
Тогда, даже если вы используете CLOSE и DEALLOCATE своим курсором, если вы вызовете этот CURSOR обратно своим @@FETCH_STATUS = -1 и если вы основываете условие цикла на @@FETCH_STATUS <> -1, ваш цикл никогда не выполняется.
Мое решение состояло в том, чтобы в основном сказать CURSOR вернуться к FIRST, заменить @@FETCH_STATUS обратно на 0, а затем выйти. Обратите внимание, что для CURSOR необходимо включить прокрутку, добавив ключевое слово SCROLL после имени CURSOR при его объявлении.
Вот пример. Я использовал три столбца из таблицы orderitems (элементы, на которые люди разместили заказы) для создания курсора:
USE transact_Sales;
GO
DECLARE @isOrderNumber INT;
DECLARE @isOrderTotal MONEY;
DECLARE test SCROLL CURSOR
FOR
SELECT Oi.order_num, SUM(Oi.quantity@item_price) FROM orderitems AS Oi GROUP BY order_num;
OPEN test;
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM test INTO @isOrderNumber, @isOrderTotal
PRINT CAST(@isOrderNumber AS VARCHAR(20)) + ' '
+CAST(@isOrderTotal AS VARCHAR(20)) + ' '
+CAST(@@FETCH_STATUS AS VARCHAR(5))
END
FETCH FIRST FROM test INTO @isOrderNumber, @isOrderTotal
CLOSE test;
DEALLOCATE test;
Вот результаты:
20005 149.87 0
20006 55.00 0
20007 1000.00 0
20008 125.00 0
20009 38.47 0
20009 38.47 -1
Курсор можно перемещать снова и снова, и каждый раз будет выдавать одни и те же результаты.
Старая ветка, которую я знаю, но ответ, найденный в другом месте, который сработал для меня, был:
WHILE (1 = 1)
BEGIN
FETCH NEXT FROM mycursor INTO @somevar
IF (@@FETCH_STATUS <> 0) BREAK
-- do stuff here
END
Не могли бы вы объяснить, почему такое поведение желательно? Возможно, сообщество сможет решить вашу проблему по-другому.