Обновить извлеченные строки в SQL Server

У меня есть хранимая процедура, которая выглядит так:

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.

Как мне это сделать?

Что такое @take и @skip? У них нет типа данных.

Thom A 23.12.2020 18:40

Действительно ли нужно делать пейджинг по обновлению? Это создает условия для гонки.

GMB 23.12.2020 18:40
delcare @countRowNumbers int; также недействителен, и вам не хватает END.
Thom A 23.12.2020 18:48

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

Stefan0309 23.12.2020 18:56
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
4
94
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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'

Stefan0309 23.12.2020 20:36

@ Стефан0309 . . . Имя столбца и имя таблицы исходят из вашего вопроса. CTE выбирает все столбцы.

Gordon Linoff 23.12.2020 20:39

да, но это просто не работает... столбец обновления не обнаружен вне этого оператора выбора.

Stefan0309 23.12.2020 20:40

хорошо, я понял, мне нужно выбрать в предложении select, чтобы я мог его обновить :)

Stefan0309 23.12.2020 20:47

@ Стефан0309 . . . Вот скрипт db<>, иллюстрирующий эту идею: dbfiddle.uk/….

Gordon Linoff 23.12.2020 20:48

это работает, но хранимая процедура не возвращает запрос выбора.

Stefan0309 23.12.2020 21:13

@ Стефан0309 . . . Ваш вопрос — настолько ясно, насколько я могу его интерпретировать — звучит так: «Мне нужно обновить статус статуса до 2». Вот что делает этот ответ.

Gordon Linoff 23.12.2020 21:40

нет, вы можете видеть, что процедура alter возвращает оператор выбора, вопрос заключался в том, как обновить эти строки и по-прежнему возвращать запрос выбора

Stefan0309 23.12.2020 21:42
Ответ принят как подходящий

Комбинируя другие ответы, используя обновляемый 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;

Другие вопросы по теме