Você perdeu algumas outras partes do livro. Sim, Steven é verdade – se ocorrer uma exceção em um bloco, todos os efeitos DML anteriores permanecem em vigor. No entanto, deve haver outra menção no livro de que qualquer execução de instrução SQL ou PL/SQL de nível superior (ou seja, bloco anônimo também) abre um cursor para essa instrução e, se houver uma exceção durante a execução do cursor, todos os efeitos DML feitos durante a execução do cursor são revertidas. Talvez um simples exemplo lhe dê a pista...
No seu exemplo original, você executou ...
BEGIN
DELETE FROM dml_exception;
raise value_error;
END;
... como a declaração de nível superior. Sim, no final do bloco, embora ainda dentro, seu
delete
efeitos permaneceram no lugar. No entanto, seu bloco gerou uma exceção que foi propagada até o cursor de nível superior. Assim, para aderir aos princípios de atomicidade
, o Oracle reverteu todos os efeitos pendentes do cursor aberto. Se você chamar seu bloco PL/SQL de dentro de outro bloco PL/SQL de nível superior, que trata e não re-aumenta a exceção gerada no bloco PL/SQL de nível inferior, ...
BEGIN
BEGIN
DELETE FROM dml_exception;
raise value_error;
END;
EXCEPTION
WHEN others THEN NULL;
END;
..., então seu
delete
efeitos devem permanecer em vigor. (E como não há commit nesse bloco, você acaba tendo uma transação em andamento.)