Nano Hash - криптовалюты, майнинг, программирование

T-SQL: итерация курсора не останавливается на @@FETCH_STATUS=-1

Я создал простой курсор в хранимой процедуре. Курсор просто перебирает все строки таблицы.

Из моего вывода кажется, что итератор извлекает n+1 строк.

Я пытался разорвать цикл while итерации, но это не решает проблему. Почему?

ALTER PROC spInsertNewCategory --spInsertNewCategory '-1','-1'
@categoryName NVARCHAR(80),
@categoryInfo NVARCHAR(80)
AS 
BEGIN

    DECLARE @siteLanguage_id      INT
    DECLARE @lang_id              INT
    DECLARE @default_siteLanguage INT

    DECLARE cr_siteLanguage       CURSOR
    FOR 
    SELECT sl.siteLanguage_id, sl.lang_id, sl.default_siteLanguage 
    FROM siteLanguage sl


    OPEN cr_siteLanguage
        FETCH NEXT FROM cr_siteLanguage
        INTO @siteLanguage_id,@lang_id,@default_siteLanguage
        PRINT '@siteLanguage_id: '+ CAST(@siteLanguage_id AS NVARCHAR(3))+' fetch: '+ CAST(@@FETCH_STATUS AS NVARCHAR(5))

        WHILE (@@FETCH_STATUS = 0)
            BEGIN
            IF (@@FETCH_STATUS=-1)
                BEGIN
                PRINT 'in if -1'
                BREAK
                END
            FETCH NEXT FROM cr_siteLanguage
            INTO @siteLanguage_id,@lang_id,@default_siteLanguage
            PRINT '@siteLanguage_id: '+ CAST(@siteLanguage_id AS NVARCHAR(3))+' fetch: '+ CAST(@@FETCH_STATUS AS NVARCHAR(5))
            END
    CLOSE cr_siteLanguage
    DEALLOCATE cr_siteLanguage 

    SELECT * FROM siteLanguage
END

введите здесь описание изображениявведите здесь описание изображения


  • Зачем вообще использовать для этого cursor? Кажется довольно простым — просто используйте правильный подход на основе набора и покончим с этим. Он будет работать намного быстрее, и вам не придется возиться с @@FETCH_STATUS и прочим.... 27.09.2014
  • @marc_s: Это просто проверка функциональности курсора, я не фанат курсоров, но у меня есть случай, когда курсор — мой лучший вариант (да, я принимаю Темную сторону). Специально для обслуживания кода. Аспект производительности не имеет значения, поскольку код курсора должен перебирать примерно 100 строк один раз в месяц. Я использую этот код для настройки/обслуживания сайта. И да, как вы сказали, подход, основанный на наборах, - это то, как все должно делаться в sql. 27.09.2014

Ответы:


1

Да, он останавливается на @@FETCH_STATUS=-1
Вот почему вы не видите свой PRINT 'in if -1'
При последнем FETCH @@FETCH_STATUS=-1 и он выходит из WHILE (@@ FETCH_STATUS = 0)

Нет, он не извлекает n+1 строк.
При n+1 он знает, что строк больше нет.
Курсор не знает, когда это последняя строка, он узнает только, когда больше нет строк. строк (n+1)
Вот почему вы выбираете первую строку перед циклом
Вы печатаете после FETCH внутри цикла
Таким образом, вы получаете последний -1
Затем он выпадает из цикла ПОКА (@@FETCH_STATUS = 0)
Запустите его в режиме отладки и посмотрите

OPEN cr_siteLanguage
        FETCH NEXT FROM cr_siteLanguage
        INTO @siteLanguage_id,@lang_id,@default_siteLanguage

        WHILE (@@FETCH_STATUS = 0)
            BEGIN
            PRINT '@siteLanguage_id: '+ CAST(@siteLanguage_id AS NVARCHAR(3))+' fetch: '+ CAST(@@FETCH_STATUS AS NVARCHAR(5))
            IF (@@FETCH_STATUS=-1)
                BEGIN
                PRINT 'in if -1'
                BREAK
                END
            FETCH NEXT FROM cr_siteLanguage
            INTO @siteLanguage_id,@lang_id,@default_siteLanguage               
            END
    CLOSE cr_siteLanguage
    DEALLOCATE cr_siteLanguage 
27.09.2014
  • Да, это была досадная ошибка. 27.09.2014

  • 2

    Похоже, что IF (@@FETCH_STATUS=-1) никогда не будет выполняться, если @@FETCH_STATUS=-1,
    вы проверяете значение @@FETCH_STATUS сразу после входа в цикл,
    у которого есть условие WHERE (@@FETCH_STATUS = 0).

    вы, вероятно, могли бы проверить после FETCH NEXT stmt внутри цикла.

    WHILE (@@FETCH_STATUS = 0)
    BEGIN
        FETCH NEXT FROM cr_siteLanguage
        INTO @siteLanguage_id,@lang_id,@default_siteLanguage
        PRINT '@siteLanguage_id: '+ CAST(@siteLanguage_id AS NVARCHAR(3))+' fetch: '+ CAST(@@FETCH_STATUS AS NVARCHAR(5))
        IF (@@FETCH_STATUS=-1)
        BEGIN
            PRINT 'in if -1'
            BREAK
        END
    END
    

    Примечание. Я предполагаю, что первый FETCH NEXT stmt (сразу после OPEN cr_siteLanguage) извлекает записи.

    27.09.2014
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..