Во-первых, вы обычно не используете DBMS_OUTPUT
для регистрации. Как правило, было бы гораздо разумнее записать данные в таблицу журнала, особенно если ваша процедура регистрации была определена как автономная транзакция, чтобы вы могли отслеживать данные журнала во время выполнения процедуры. DBMS_OUTPUT
будет отображаться только после того, как вся процедура будет завершена, и в этот момент она обычно несколько бессмысленна
Относительно этого первого пункта полагаться на DBMS_OUTPUT
, чтобы указать вызывающему абоненту, что произошло какое-то исключение, - очень плохая практика. Как минимум, вам нужно повторно вызвать исключение, которое было сгенерировано, чтобы получить стек ошибок для устранения проблемы.
Во-вторых, когда вы включаете вывод, вы должны указать размер буфера, в который DBMS_OUTPUT
может записывать. Похоже, что вы объявили буфер 20 000 байтов, что по умолчанию, если вы просто
SQL> set serveroutput on;
Вы можете изменить это, указав размер, но максимальный размер ограничен 1 000 000 байтов
SQL> set serveroutput on size 1000000;
Если вы планируете обновить 3 миллиарда строк в 1000 кусочках строк, это будет слишком маленький буфер. Вы будете генерировать более чем в 60 раз больше данных с вашим текущим кодом. Если вы используете 10.2 как на клиенте, так и на сервере, вы сможете выделить неограниченный буфер
SQL> set serveroutput on size unlimited;
но это не вариант в более ранних выпусках.
Наконец, вы уверены, что вам нужно в первую очередь прибегнуть к PL / SQL? Похоже, что вы могли бы сделать это более эффективно, просто выполнив одно UPDATE
UPDATE table_
SET id = floor( seq/ 10000000000000 )
WHERE id is null;
Это намного меньше кода, его гораздо легче читать, и он будет более эффективным, чем альтернатива PL / SQL. Единственным недостатком является то, что требуется, чтобы ваше табличное пространство UNDO было достаточно большим, чтобы вместить генерируемую UNDO, но при обновлении одного столбца из NULL в ненулевое числовое значение не должно генерироваться столько UNDO.