Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Prozedur Pufferüberlauf

Zunächst einmal würden Sie normalerweise DBMS_OUTPUT nicht verwenden zum Loggen. Generell ist es viel sinnvoller, die Daten in eine Protokolltabelle zu schreiben, insbesondere wenn Ihr Protokollierungsverfahren als eigenständige Transaktion definiert wurde, um die Protokolldaten während des Ablaufs überwachen zu können. DBMS_OUTPUT wird erst angezeigt, nachdem die gesamte Prozedur ausgeführt wurde, an welcher Stelle es im Allgemeinen etwas sinnlos ist.

Bezogen auf diesen ersten Punkt, sich auf DBMS_OUTPUT verlassend Dem Anrufer anzuzeigen, dass es eine Art Ausnahme gegeben hat, ist eine sehr schlechte Praxis. Zumindest sollten Sie die ausgelöste Ausnahme erneut auslösen, damit Sie den Fehlerstapel erhalten, um das Problem zu debuggen.

Zweitens, wenn Sie die Ausgabe aktivieren, müssen Sie die Größe des Puffers angeben, der DBMS_OUTPUT ist anschreiben kann. Es scheint, dass Sie den Puffer mit 20.000 Byte deklariert haben, was der Standardwert ist, wenn Sie einfach

SQL> set serveroutput on;

Sie können dies ändern, indem Sie eine Größe angeben, aber die maximale Größe ist auf 1.000.000 Byte begrenzt

SQL> set serveroutput on size 1000000;

Wenn Sie planen, 3 Milliarden Zeilen in 1000-Zeilen-Blöcken zu aktualisieren, ist das ein viel zu kleiner Puffer. Sie werden mit Ihrem aktuellen Code mehr als das 60-fache dieser Datenmenge generieren. Wenn Sie 10.2 sowohl auf dem Client als auch auf dem Server verwenden, sollten Sie in der Lage sein, einen unbegrenzten Puffer zuzuweisen

SQL> set serveroutput on size unlimited;

aber das ist keine Option in früheren Versionen.

Sind Sie sich schließlich sicher, dass Sie überhaupt auf PL/SQL zurückgreifen müssen? Es scheint, dass Sie dies effizienter tun könnten, indem Sie einfach ein einzelnes UPDATE

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

Das ist viel weniger Code, viel einfacher zu lesen und effizienter als die PL/SQL-Alternative. Der einzige Nachteil ist, dass Ihr UNDO-Tablespace groß genug sein muss, um das generierte UNDO aufzunehmen, aber das Aktualisieren einer einzelnen Spalte von NULL auf einen numerischen Nicht-NULL-Wert sollte nicht so viel UNDO erzeugen.