У меня есть хранимая процедура, которая выглядит так:
alter procedure newProcedure
@take int,
@skip int
as
begin
set nocount on
declare @countRowNumbers int;
set @countRowNumbers = (select count(*) from TableA)
select *
from tableA a
order by a.ID
offset ISNULL(@skip,0) rows
fetch next ISNULL(@take, @countRowNumbers) rows only
--update only fetched rows (first 100, or second 100)
-- update TableA set Status = 2
end
У меня есть статус столбца, который показывает, обрабатывается строка или нет, поэтому, когда я беру эти 100 документов, мне нужно обновить этот статус статуса до 2.
Как мне это сделать?
Действительно ли нужно делать пейджинг по обновлению? Это создает условия для гонки.
delcare @countRowNumbers int;
также недействителен, и вам не хватает END
.
извините, ребята, я печатал с другой удаленной машины .. Пожалуйста, посмотрите мой обновленный вопрос. Также приветствуются любые предложения о том, как выполнить пейджинг без использования выборки!
alter procedure newProcedure
@take int,
@skip int
as
begin
set nocount on
declare @countRowNumbers int;
set @countRowNumbers = (select count(*) from TableA)
update tableA set status = 2 where ID in (
select a.ID
from tableA a
order by a.ID
offset ISNULL(@skip,0) rows
fetch next ISNULL(@take, @countRowNumbers) rows only )
--update only fetched rows (first 100, or second 100)
-- update TableA set Status = 2
end
Для этого вы должны иметь возможность использовать обновляемый CTE:
with toupdate as (
select *
from tableA a
order by a.ID
offset ISNULL(@skip,0) rows
fetch next ISNULL(@take, @countRowNumbers) rows only
)
update toupdate
set status = 2;
не работает пишет Msg 207, Level 16, State 1, Procedure newProcedure, Line 14 [Btach Start Line 12] Invalid column name 'status'
@ Стефан0309 . . . Имя столбца и имя таблицы исходят из вашего вопроса. CTE выбирает все столбцы.
да, но это просто не работает... столбец обновления не обнаружен вне этого оператора выбора.
хорошо, я понял, мне нужно выбрать в предложении select, чтобы я мог его обновить :)
@ Стефан0309 . . . Вот скрипт db<>, иллюстрирующий эту идею: dbfiddle.uk/….
это работает, но хранимая процедура не возвращает запрос выбора.
@ Стефан0309 . . . Ваш вопрос — настолько ясно, насколько я могу его интерпретировать — звучит так: «Мне нужно обновить статус статуса до 2». Вот что делает этот ответ.
нет, вы можете видеть, что процедура alter возвращает оператор выбора, вопрос заключался в том, как обновить эти строки и по-прежнему возвращать запрос выбора
Комбинируя другие ответы, используя обновляемый CTE для выполнения update
сначала, затем используя предложение output для захвата обновленных идентификаторов, а затем select
их для возврата.
declare @SelectedId table (id int);
with toupdate as (
select *
from tableA a
order by a.ID
offset isnull(@skip,0) rows
fetch next isnull(@take, @countRowNumbers) rows only
)
update toupdate
set [status] = 2
output Inserted.id into @SelectedId;
select *
from tableA
where ID in (select id from @SelectedId)
order by ID;
Что такое
@take
и@skip
? У них нет типа данных.