Name
SQL-02: Use incremental COMMITs to avoid rollback segment errors when changing large numbers of rows.
Synopsis
It’s very easy to issue an UPDATE statement that can (theoretically) change one million rows or 10 million rows. It’s more of a challenge to get that statement to succeed without running out of rollback segment space. And these errors are often hard to predict, because they depend on the volume of data for a specific run.
If you have this problem, you should switch to incremental commits: issue a COMMIT statement every 1,000 or 10,000 rows—whatever level works for your rollback segments.
Example
You can declare a counter variable and update the variable with each execution of the loop body. If you process data from within a cursor FOR loop, you can also take advantage of the built-in %ROWCOUNT attribute, as shown here:
DECLARE c_commit_plateau CONSTANT PLS_INTEGER := 10000; CURSOR my_cur IS SELECT * FROM my_table; BEGIN FOR my_rec IN my_cur LOOP INSERT INTO temp_data VALUES (my_rec.id); IF (MOD (my_cur%rowcount, c_commit_plateau) = 0) THEN COMMIT WORK; END IF; END LOOP; COMMIT WORK; END;
You can also build an API to the PL/SQL COMMIT statement that automatically handles incremental commits and adds value (logging, on-off toggles) to COMMIT. You can find an example of such a package in the PL/Vision library.
Benefits
Make your code more robust by avoiding hard-to-predict rollback segment errors in your programs.
When you use %ROWCOUNT, there’s no need to declare a local ...
Get Oracle PL/SQL Best Practices now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.