Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Estouro de buffer de procedimento


Primeiramente, você normalmente não usaria DBMS_OUTPUT para logar. Em geral, faria muito mais sentido gravar os dados em uma tabela de log, especialmente se seu procedimento de log fosse definido como uma transação autônoma para que você pudesse monitorar os dados de log enquanto o procedimento estivesse em execução. DBMS_OUTPUT só será exibido depois que todo o procedimento terminar de ser executado, ponto em que geralmente é um pouco inútil.

Relacionado a esse primeiro ponto, contando com DBMS_OUTPUT indicar ao chamador que houve algum tipo de exceção é uma prática muito ruim. No mínimo, você deseja aumentar novamente a exceção que foi lançada para obter a pilha de erros para depurar o problema.

Segundo, quando você habilita a saída, você precisa especificar o tamanho do buffer que DBMS_OUTPUT pode escrever para. Parece que você declarou o buffer como 20.000 bytes, que é o padrão se você simplesmente
SQL> set serveroutput on;

Você pode alterar isso especificando um tamanho, mas o tamanho máximo é limitado a 1.000.000 bytes
SQL> set serveroutput on size 1000000;

Se você planeja atualizar 3 bilhões de linhas em blocos de 1.000 linhas, esse buffer será muito pequeno. Você vai gerar mais de 60 vezes essa quantidade de dados com seu código atual. Se você estiver usando 10.2 no cliente e no servidor, poderá alocar um buffer ilimitado
SQL> set serveroutput on size unlimited;

mas isso não é uma opção em versões anteriores.

Finalmente, você tem certeza de que precisa recorrer ao PL/SQL em primeiro lugar? Parece que você poderia fazer isso com mais eficiência simplesmente executando um único UPDATE
UPDATE table_
   SET id = floor( seq/ 10000000000000 )
 WHERE id is null;

Isso é muito menos código, muito mais fácil de ler e será mais eficiente do que a alternativa PL/SQL. A única desvantagem é que ele requer que seu espaço de tabela UNDO seja grande o suficiente para acomodar o UNDO que é gerado, mas atualizar uma única coluna de NULL para um valor numérico não NULL não deve gerar tanto UNDO.