Oracle
 sql >> Base de données >  >> RDS >> Oracle

DML et gestion des exceptions - Oracle

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.)