Previous Entry Share Next Entry
Хозяйке на заметку
zinal
Если в крупной таблице необходимо обновить большое количество записей, легко "упереться" в ограничение на объём операций в рамках одной транзакции (в одном операторе). Для Oracle Database ограничивающим фактором оказывается предельный размер UNDO, для IBM Db2 - размер активной части журнала транзакций, и т.п. В любом случае, размер транзакции ограничен объёмом памяти, в которую записываются данные для отката этой транзакции.
Решение данного затруднения очевидно — нужно разбить крупную операцию на последовательность более мелких, с промежуточным подтверждением каждой транзакции. Требуется лишь понять, как ограничить размер единичной транзакции.
Проще всего опираться на количество изменённых записей. Современные СУБД позволяют ограничить количество изменяемых запросом записей. Также при выполнении запроса на изменение данных обычно можно, после завершения запроса, определить количество изменённых строк, либо, как минимум, факт отсутствия выполненных запросом изменений - это можно использовать как условие для остановки алгоритма.
Пример для Db2:

db2 -td@
BEGIN
  DECLARE SQLCODE INTEGER DEFAULT 0;
  DECLARE retcode INTEGER DEFAULT 1;
  WHILE (retcode > 0) DO
    UPDATE mytab SET date_oper=CAST('29.10.2012' as date)+ (300*RAND()) 
      WHERE date_oper IS NULL FETCH FIRST 100000 ROWS ONLY;
    SET retcode = SQLCODE;
    SET retcode = CASE WHEN retcode=100 THEN 0 ELSE 1 END;
    COMMIT;
  END WHILE;
END @
Tags: , ,

?

Log in

No account? Create an account