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

PL/SQL :existe-t-il une instruction pour arrêter complètement l'exécution du script ?

La question montre un script batch multi-instructions. RAISE_APPLICATION_ERROR() ne sort que d'un bloc PL/SQL (sous-programme), pas du script global (comme l'a souligné Justin) donc il continuera avec les instructions qui suivent.

Pour les scripts batch, il est préférable d'utiliser WHENEVER SQLERROR EXIT. Oui, c'est une directive SQLPlus, pas du SQL standard, mais elle est assez portable ; les outils Oracle les plus populaires qui prennent en charge les scripts prennent en charge cette directive, au moins partiellement. L'exemple suivant fonctionne en SQL De plus, SQL*Developer, Toad, SQLsmith et peut-être d'autres, et illustre le problème, si vous commentez la ligne.

set serveroutput on

-- Without this line, things keep going
WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK;

BEGIN
  IF (1 > 0) THEN
    DBMS_OUTPUT.PUT_LINE('First thing');
    RAISE_APPLICATION_ERROR(-20000, 'Test failed'); -- not enough
  END IF;
END;
/

-- This will execute if you remove WHEN SQLERROR.., so RAISE_APPLICATION_ERROR is not enough
BEGIN
   DBMS_OUTPUT.PUT_LINE('Second thing - Executes anyway');
END;
/

Si vous supprimez WHEN SQLERROR, le script continuera et exécutera le 2ème bloc, etc., ce qui est exactement ce que la question demande d'éviter.

L'avantage, dans ce cas, des outils graphiques qui émulent sqlplus, est qu'ils arrêtent vraiment le script et ne soumettent pas le reste du script au shell de commande en tant que commandes shell, ce qui se produit si vous collez des scripts dans SQLPlus s'exécutant dans une fenêtre de console. SQL Plus peut se fermer en cas d'erreur, mais les commandes restantes en mémoire tampon seront alors gérées par le shell du système d'exploitation, ce qui est un peu désordonné et potentiellement risqué, si vous aviez des commandes shell dans les commentaires (ce qui n'est pas rare). Avec SQLPlus, il est toujours préférable de se connecter, puis d'exécuter le script, ou de le passer dans l'argument de ligne de commande (sqlplus scott/tiger @foo.sql) pour éviter cela.