Za prvé, předpokládám, že můžeme ignorovat syntaktické chyby (například neexistuje žádný END LOOP
, dbms_output.put_line
volání chybí první jednoduchá uvozovka atd.)
Na tom, zda je nutné vrátit změny, záleží.
Obecně byste neměli prozatímní commity ve smyčce. To je obecně špatná architektura, protože je mnohem nákladnější z hlediska I/O a uplynulého času. Také je mnohem těžší psát restartovatelný kód. Co se například stane, pokud váš SELECT
příkaz vybere 10 řádků, vydáte (a odevzdáte) 5 aktualizací a pak se 6. aktualizace nezdaří? Jediným způsobem, jak restartovat s 6. řádkem poté, co jste opravili výjimku, by bylo mít samostatnou tabulku, kde byste ukládali (a aktualizovali) průběh vašeho kódu. To také vytváří problémy pro jakýkoli kód, který volá tento blok, který se pak musí vypořádat s případem, že polovina práce byla vykonána (a potvrzena) a druhá polovina ne.
Obecně platí, že byste příkazy řízení transakcí umístili pouze do nejvzdálenějších bloků vašeho kódu. Od COMMIT
nebo ROLLBACK
v proceduře odevzdává nebo odvolává jakoukoli práci vykonanou v relaci bez ohledu na to, zda ji provedla procedura, chcete být velmi opatrní při přidávání příkazů řízení transakcí. Obecně chcete nechat volajícího, aby se rozhodl, zda se zavázat nebo vrátit zpět. Samozřejmě, že to jde jen tak daleko – nakonec se ocitnete v nejvzdálenějším bloku, který nebude nikdy volán z nějaké jiné rutiny a musíte mít vhodnou kontrolu transakcí – ale je třeba být velmi ostražitý o tom, zda píšete kód, který lze znovu použít.
V tomto případě, protože máte prozatímní odevzdání, jediný efekt vašeho ROLLBACK
by bylo, že pokud selže první příkaz aktualizace, práce, která byla provedena ve vaší relaci před voláním tohoto bloku, by byla vrácena zpět. Prozatímní potvrzení potvrdí tyto předchozí změny, pokud bude první aktualizační příkaz úspěšný. To je druh vedlejšího efektu, kterého se lidé obávají, když mluví o tom, proč jsou prozatímní závazky a kontrola transakcí v opakovaně použitelných blocích problematické.