Ключом к выполнению этой работы является выполнение работы на сервере вместо того, чтобы сервер выбирал каждую строку, передавал ее клиенту и затем принимал данные обратно от клиента.
UPDATE YourTable
SET y = (CASE WHEN z > x THEN p ELSE y)
WHERE key_column BETWEEN lo_val AND hi_val;
Сложная часть, вероятно, будет разделять работу на управляемые суб-транзакции; это то, о чем говорит условие lo_val .. hi_val. Если ваши логические журналы достаточно велики, чтобы обрабатывать все 130 миллионов обновляемых строк [около (2 * (размер строки + X) * количество строк), при этом значение X составляет около 20, я полагаю) с запасом места, то вы можно сделать все сразу. Очевидно, это «обновляет» каждую строку.
Если вы решили, что должны сделать это на клиенте (ошибка, но ...), тогда:
Вы используете курсор SELECT с HOLD, чтобы он оставался открытым и правильно позиционировался между транзакциями. Вы начинаете транзакцию, выбираете несколько тысяч строк и обновляете каждую по мере необходимости. Убедитесь, что вы используете подготовленный оператор UPDATE; может быть, вы используете условие WHERE CURRENT OF.
Предлагаете ли вы поместить обновление как часть курсора в хранимую процедуру?
Нет, хотя вы можете сделать это в хранимой процедуре. Частично это зависит от того, будете ли вы этим заниматься регулярно; если это так, может быть, хранимая процедура - это хорошая идея, но я бы не стал делать одноразовое упражнение.
Это зависит от того, как вы собираетесь определять lo_val и hi_val. Я бы, вероятно, использовал I4GL (потому что я бегло в этом разбираюсь), а затем я ожидал бы подготовить оператор UPDATE (с вопросительными знаками вместо 'lo_val' и 'hi_val'), а затем я ожидал бы выполнить это несколько раз, каждый раз формируя одну транзакцию оператора. Итак, если вы решили использовать диапазоны lo_val..hi_val от 000000..099999, 100000..199999, ... тогда вы должны выполнить итерацию:
for i = 0 to 10000000 step 100000
let j = i + 99999
execute p_update using i, j
end for
В I4GL вам совершенно не нужно использовать подготовленное утверждение. Если у вас есть IDS 11, вы можете подготовить заявления в SPL. В более ранних версиях и без значительного снижения производительности (я сомневаюсь, что вы могли бы измерить его достоверно), вы могли бы просто использовать:
CREATE PROCEDURE update_your_table()
DEFINE lo_val, hi_val INTEGER;
FOR lo_val = 0 TO 1000000 STEP 100000
LET hi_val = lo_val + 99999;
UPDATE YourTable
SET y = (CASE WHEN z > x THEN p ELSE y)
WHERE key_column BETWEEN lo_val AND hi_val;
END FOR;
END PROCEDURE;
Непроверенный код - используйте на свой страх и риск!