Подтвердить что ты не робот

Как я могу выполнить SQL UPDATE в пакетах, например, Update Top?

Можно ли добавить TOP или какой-то пейджинг в инструкцию SQL Update?

У меня есть запрос UPDATE, который сводится к следующему:

UPDATE XXX SET XXX.YYY = #TempTable.ZZZ
FROM XXX
INNER JOIN (SELECT SomeFields ... ) #TempTable ON XXX.SomeId=#TempTable.SomeId
WHERE SomeConditions

Это обновление повлияет на миллионы записей, и мне нужно делать это партиями. Как и 100 000 в то время (заказ не имеет значения)

Каков самый простой способ сделать это?

4b9b3361

Ответ 1

Да, я считаю, что вы можете использовать TOP в операторе обновления, например:

UPDATE TOP (10000) XXX SET XXX.YYY = #TempTable.ZZZ
FROM XXX
INNER JOIN (SELECT SomeFields ... ) #TempTable ON XXX.SomeId=#TempTable.SomeId
WHERE SomeConditions

Ответ 2

Вы можете использовать SET ROWCOUNT { number | @number_var }, он ограничивает количество обработанных строк перед остановкой конкретного запроса, пример ниже:

SET ROWCOUNT 10000 -- define maximum updated rows at once

UPDATE XXX SET 
    XXX.YYY = #TempTable.ZZZ
FROM XXX
INNER JOIN (SELECT SomeFields ... ) #TempTable ON XXX.SomeId = #TempTable.SomeId
WHERE XXX.YYY <> #TempTable.ZZZ and OtherConditions

-- don't forget about bellow 
-- after everything is updated
SET ROWCOUNT 0

Я добавил предложение XXX.YYY <> #TempTable.ZZZ в where, чтобы убедиться, что вы не обновите дважды уже обновленное значение.

Настройка ROWCOUNT на 0 отключить ограничения - не забывайте об этом.

Ответ 3

В зависимости от вашей способности изменять структуру данных таблицы, я бы предположил, что вы добавляете поле в свою таблицу, которое может содержать какой-то пакетный идентификатор. То есть. это может быть отметка даты, если вы делаете это ежедневно, добавочное значение или в основном любое значение, которое вы можете сделать уникальным для своей партии. Если вы примете инкрементный подход, ваше обновление будет следующим:

UPDATE TOP (100000) XXX SET XXX.BATCHID = 1, XXX.YYY = ....
...
WHERE XXX.BATCHID < 1 
  AND (rest of WHERE-clause here).

В следующий раз вы установите BATCHID = 2 и WHERE XXX.BATCHID < 2

Если это нужно сделать многократно, вы можете установить индекс на BATCHID и уменьшить нагрузку на сервер.

Ответ 4

Вы можете сделать что-то вроде следующего

declare @i int = 1
while @i <= 10 begin

    UPDATE  top (10) percent
            masterTable set colToUpdate = lt.valCol
    from    masterTable as mt
            inner join lookupTable as lt
                    on mt.colKey = lt.colKey
    where colToUpdate is null

    print @i
    set @i += 1
end

--one final update without TOP (assuming lookupTable.valCol is mostly not null)
UPDATE  --top (10) percent
        masterTable set colToUpdate = lt.valCol
from    masterTable as mt
        inner join lookupTable as lt
                on mt.colKey = lt.colKey            
where colToUpdate is null