Vous avez manqué d'autres parties du livre. Oui, Steven est vrai - si une exception se produit dans un bloc, tous les effets DML précédents restent en place. Pourtant, il devrait y avoir une autre mention dans le livre que toute exécution d'instruction SQL ou PL/SQL de haut niveau (c'est-à-dire un bloc anonyme également) ouvre un curseur pour cette instruction et s'il y a une exception lors de l'exécution du curseur, tous les effets DML effectués pendant l'exécution du curseur sont annulées. Peut-être qu'un simple exemple vous donnera l'indice...
Dans votre exemple original, vous avez exécuté ...
BEGIN
DELETE FROM dml_exception;
raise value_error;
END;
... comme instruction de niveau supérieur. Oui, à la fin du bloc, mais toujours à l'intérieur, votre delete
les effets sont restés en place. Pourtant, votre bloc a déclenché une exception qui s'est propagée jusqu'au curseur de niveau supérieur. Ainsi, afin de respecter les principes d'atomicité
, Oracle a annulé tous les effets en attente du curseur ouvert.
Si vous appelez votre bloc PL/SQL à partir d'un autre bloc PL/SQL de niveau supérieur, qui gère et ne relance pas l'exception déclenchée dans le bloc PL/SQL de niveau inférieur, ...
BEGIN
BEGIN
DELETE FROM dml_exception;
raise value_error;
END;
EXCEPTION
WHEN others THEN NULL;
END;
..., puis votre delete
les effets doivent rester en place. (Et comme il n'y a pas de validation dans ce bloc, vous finissez par avoir une transaction en cours.)