Oracle
 sql >> Database >  >> RDS >> Oracle

Procedura Overflow del buffer

Prima di tutto, normalmente non useresti DBMS_OUTPUT per la registrazione. In genere avrebbe molto più senso scrivere i dati in una tabella di registro, in particolare se la procedura di registrazione è stata definita come una transazione autonoma in modo da poter monitorare i dati di registro mentre la procedura è in esecuzione. DBMS_OUTPUT verrà visualizzato solo al termine dell'esecuzione dell'intera procedura, a quel punto è generalmente alquanto inutile.

Relativo a quel primo punto, basandosi su DBMS_OUTPUT indicare al chiamante che si è verificata una sorta di eccezione è una pratica molto scarsa. Come minimo, vorresti sollevare nuovamente l'eccezione che è stata generata in modo da ottenere lo stack di errori per eseguire il debug del problema.

In secondo luogo, quando abiliti l'output, devi specificare la dimensione del buffer che DBMS_OUTPUT può scrivere a. Sembra che tu abbia dichiarato che il buffer è di 20.000 byte, che è l'impostazione predefinita se semplicemente

SQL> set serveroutput on;

Puoi cambiarlo specificando una dimensione, ma la dimensione massima è limitata a 1.000.000 di byte

SQL> set serveroutput on size 1000000;

Se prevedi di aggiornare 3 miliardi di righe in blocchi di 1000 righe, sarà un buffer troppo piccolo. Genererai più di 60 volte quella quantità di dati con il tuo codice attuale. Se stai usando 10.2 sia sul client che sul server, dovresti essere in grado di allocare un buffer illimitato

SQL> set serveroutput on size unlimited;

ma questa non è un'opzione nelle versioni precedenti.

Infine, sei sicuro di dover ricorrere in primo luogo a PL/SQL? Sembra che potresti farlo in modo più efficiente semplicemente eseguendo un singolo UPDATE

UPDATE table_
   SET id = floor( seq/ 10000000000000 )
 WHERE id is null;

Questo è molto meno codice, molto più facile da leggere e sarà più efficiente dell'alternativa PL/SQL. L'unico aspetto negativo è che richiede che lo spazio tabella UNDO sia sufficientemente grande da contenere l'UNDO generato, ma l'aggiornamento di una singola colonna da NULL a un valore numerico non NULL non dovrebbe generare molto UNDO.