SQL курсор переходит в бесконечный цикл - PullRequest
0 голосов
/ 09 апреля 2020

Это sql входит в бесконечное l oop.

Я не могу найти, что с ним не так. Я искал другой пост, но в большинстве случаев они пропустили последний оператор извлечения перед конечным тегом. Я уверен, что что-то упустил, но не могу сказать, что это. Так я что-то пропустил?

Ниже мои коды

    DECLARE 
    @counter INT = 1042,
    @overwrite_text NVARCHAR(250), 
    @sequence INT,
    @is_correct BIT,
    @score INT,
    --@form_question_id INT,
    @question_answer_id INT;

DECLARE cursor_form_answer CURSOR
FOR SELECT
      [overwrite_text]
      ,[sequence]
      ,[is_correct]
      ,[score]
      --,[form_question_id]
      ,[question_answer_id]
  FROM [form_question_answer];

OPEN cursor_form_answer;

FETCH NEXT FROM cursor_form_answer INTO 
    @overwrite_text, 
    @sequence,
    @is_correct,
    @score,
    --@form_question_id,
    @question_answer_id;

WHILE @@FETCH_STATUS = 0
    BEGIN

        INSERT INTO [form_question_answer] (overwrite_text, sequence, is_correct, score, form_question_id, question_answer_id)
        VALUES (@overwrite_text, @sequence, @is_correct, @score, @counter, @question_answer_id);

        SET @counter = @counter + 1;

        FETCH NEXT FROM cursor_form_answer INTO 
            @overwrite_text, 
            @sequence,
            @is_correct,
            @score,
            --@form_question_id,
            @question_answer_id;
    END;

CLOSE cursor_form_answer;

DEALLOCATE cursor_form_answer;

Ответы [ 3 ]

1 голос
/ 09 апреля 2020

Да, потому что вы вставили записи в ту же таблицу, которую используете для l oop. Например, если у вас есть запись в таблице, вставленная вами запись будет следующей выборкой, поэтому будет бесконечной l oop.

0 голосов
/ 09 апреля 2020

По умолчанию курсор является динамическим c (он читает таблицу на каждой итерации). В вашем коде каждый раз, когда вы выполняете итерацию, вы также вставляете новые строки, и курсор никогда не достигает «конца» таблицы.

Если вы хотите один проход для существующих данных, просто объявите курсор как stati c:

DECLARE cursor_form_answer CURSOR STATIC

или вы можете ограничить область действия динамического c курсора только существующими строками, если ваши данные поддерживают это, например. есть столбец идентификаторов (здесь есть нюанс / «тонкая» строка относительно оценки курсора)

--this.. if sequence is autoincrement
DECLARE cursor_form_answer CURSOR 
FOR SELECT
      ...
from [form_question_answer]
where [sequence] <= (select max([sequence]) from [form_question_answer])
0 голосов
/ 09 апреля 2020

Нет необходимости в CURSOR здесь вообще. Просто INSERT данные, используя SELECT:

INSERT INTO [form_question_answer] (overwrite_text,
                                    [sequence],
                                    is_correct,
                                    score,
                                    form_question_id,
                                    question_answer_id)
SELECT [overwrite_text],
       [sequence],
       [is_correct],
       [score],
       --,[form_question_id]
       ROW_NUMBER() OVER (ORDER BY [form_question_id]),
       [question_answer_id]
FROM [form_question_answer];

Я должен сказать, однако, кажется действительно странным, что вы захватываете данные из таблицы form_question_answer и затем вставьте его обратно в стол.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...