IF-ELSE внутри курсора SQL для изменения значений записей

#sql-server-2016 #database-cursor

#sql-server-2016 #база данных-курсор

Вопрос:

У меня есть таблица SQL Server, в которой есть записи, одна из которых является номером, который мне нужно перенумеровать в новую таблицу, в ней также есть столбец identity, который будет повторяться в записях, когда их несколько. Я хотел бы отсортировать таблицу по полю идентификатора, затем по убыванию в числовом поле, затем использовать курсор для нумерации 1-й записи (1), следующей записи (2) и так далее, пока поле идентификатора не изменится, затем повторить.

Поля, которые у меня есть: load_number (идентификатор), stop_type, stop_number Данные будут выглядеть следующим образом:

load_number — stop_type — stop_number
1234 —————— 1 ——————- 1
1234 —————— 2 ——————- 5
1234 —————— 2 ——————- 4
1234 —————— 2 ——————- 3
1234 —————— 2 ——————- 2
1234 —————— 2 ——————- 1

У меня есть другие поля, которые описывают каждую строку более подробно, но мне нужно, чтобы в приведенном выше 5 стало 1, 4 стало 2, 3 осталось 3, 2 стало 4, а 1 стало 5 (поэтому полностью переверните числа), эти числа могут достигать 10.

 DECLARE @lead_key int = 1, @load_number int, @stop_type, @stop_number, @stopnum

CREATE TABLE #renumber
    (load_number int, stop_type int, stop_number int)

DECLARE stop_cursor CURSOR FAST_FORWARD FOR
  select load_number, stop_type, stop_number 
  from sometable 
  order by load_number, stop_type, stop_number desc

OPEN stop_cursor

FETCH NEXT from stop_cursor
INTO @load_number, @stop_type, @stop_number

while @@FETCH_STATUS = 0
BEGIN

If @load_key = 1
  BEGIN
  SET @load_key = @load_number  --initialize @load_key for first record
  END

If @load_key = @load_number
  BEGIN
  If @stop_type = 2
    BEGIN
    insert into #renumber
    select @load_number, @stop_type, @stopnum  --use @stopnum counter
    SET @stopnum = @stopnum   1
    END
  ELSE
    BEGIN
    insert into #renumber
    select @load_number, @stop_type, @stop_number   --use @stop_number
    SET @stopnum = 1    --reset @stopnum to 1
    END
  END
ELSE
  SET @load_key = @load_number
  SET @stopnum = 1
END

FETCH NEXT from stop_cursor
INTO @load_number, @stop_type, @stop_number

CLOSE stop_cursor;
DEALLOCATE stop_cursor;
  

Этот запрос зацикливается и никогда не заканчивается, моя способность к отладке не работает на моем ПК, поэтому я не могу пройти через это, чтобы увидеть, где происходит зацикливание, поэтому я подумал, что спрошу здесь правильный способ получить то, что я ищу. Спасибо за любую помощь!

Ответ №1:

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

Шаг 1:

 CREATE TABLE #renumber
    (ID int identity(1,1), load_number int, stop_type int, stop_number int)
  

Шаг 2: Вставьте таблицу с идентификатором, созданным автоматически

 insert into #renumber(load_number, stop_type, stop_number)
select load_number, stop_type, stop_number 
from sometable 
order by load_number, stop_type, stop_number desc
  

Шаг 3:

 DECLARE @id int, @load_number int, @stop_type, @stop_number, @stopnum int

--Static cursor

DECLARE stop_cursor CURSOR STATIC FOR
  select id, load_number, stop_type, stop_number 
  from #renumber
  order by id

OPEN stop_cursor

FETCH NEXT from stop_cursor INTO @id, @load_number, @stop_type, @stop_number

while @@FETCH_STATUS = 0
BEGIN

If @load_key = 1
  BEGIN
  SET @load_key = @load_number  --initialize @load_key for first record
  END

If @load_key = @load_number
  BEGIN
  If @stop_type = 2
    BEGIN
    --Update the value you'd like base on ID
    update #renumber set stopnum = @stopnum where id = @id
    SET @stopnum = @stopnum   1
    END
  ELSE
    BEGIN
    --Update the value you'd like base on ID
    update #renumber set stopnum = @stopnum where id = @id 
    SET @stopnum = 1    --reset @stopnum to 1
    END
  END
ELSE
  SET @load_key = @load_number
  SET @stopnum = 1
END

FETCH NEXT from stop_cursor INTO @id, @load_number, @stop_type, @stop_number

CLOSE stop_cursor;
DEALLOCATE stop_cursor;