Za prvé, normálně byste nepoužívali DBMS_OUTPUT
pro těžbu dřeva. Obecně by dávalo mnohem větší smysl zapisovat data do tabulky protokolů, zejména pokud byla vaše procedura protokolování definována jako autonomní transakce, abyste mohli sledovat data protokolu, zatímco procedura probíhala. DBMS_OUTPUT
se zobrazí až po dokončení celé procedury, kdy je to obecně poněkud zbytečné.
Souvisí s tímto prvním bodem a spoléhá se na DBMS_OUTPUT
naznačit volajícímu, že došlo k nějaké výjimce, je velmi špatná praxe. Minimálně byste chtěli znovu vyvolat výjimku, která byla vyvolána, abyste získali zásobník chyb, abyste mohli problém odladit.
Za druhé, když povolíte výstup, musíte zadat velikost vyrovnávací paměti, která DBMS_OUTPUT
může napsat. Zdá se, že jste deklarovali vyrovnávací paměť na 20 000 bajtů, což je výchozí hodnota, pokud jednoduše
SQL> set serveroutput on;
Můžete to změnit zadáním velikosti, ale maximální velikost je omezena na 1 000 000 bajtů
SQL> set serveroutput on size 1000000;
Pokud plánujete aktualizovat 3 miliardy řádků v 1000 blocích řádků, bude to příliš malá vyrovnávací paměť. Se svým aktuálním kódem vygenerujete více než 60násobek množství dat. Pokud používáte 10.2 na klientovi i na serveru, měli byste být schopni alokovat neomezenou vyrovnávací paměť
SQL> set serveroutput on size unlimited;
ale to není možnost v dřívějších verzích.
A konečně, jste si jisti, že se musíte v první řadě uchýlit k PL/SQL? Zdá se, že byste to mohli udělat efektivněji jednoduchým provedením jediné UPDATE
UPDATE table_
SET id = floor( seq/ 10000000000000 )
WHERE id is null;
To je mnohem méně kódu, mnohem snazší čtení a bude to efektivnější než alternativa PL/SQL. Jedinou nevýhodou je, že vyžaduje, aby váš tabulkový prostor UNDO byl dostatečně velký, aby se do něj vešlo vygenerované ZPĚT, ale aktualizace jednoho sloupce z NULL na číselnou hodnotu bez NULL by tolik ZPĚT generovat neměla.