#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;