2010-09-17 20 views
6

Je ne sais pas où les informations d'erreur disparaissent lorsqu'un déclencheur ne fonctionne pas correctement.Techniques de débogage Oracle

Mon outil d'écriture des déclencheurs a été l'outil Sql Developer d'Oracle, et ma connaissance de la façon de le déboguer est quasiment inexistante. Quels sont les indicateurs pour être en mesure de trouver des informations utiles sur les choses qui se passent "dans les coulisses"? Aussi, y at-il de meilleurs outils que Sql Developer pour se connecter, tester, déboguer, etc?

Ma méthode jusqu'ici a été d'écrire quelque chose (un déclencheur, par exemple), le tester avec des insertions/suppressions simples, puis espérer que cela fonctionne à partir d'eux. Y a-t-il de meilleurs moyens de s'assurer que c'est exactement ce que vous voulez? Par exemple, avec une instruction select, y a-t-il un moyen de voir (dans un état de débogage ou quelque chose) chaque niveau du select et comment il réduit les résultats? Tous les conseils grandement appréciés.

Répondre

12

Tout d'abord, tout le code fonctionne correctement. Il ne fait tout simplement pas ce que vous attendiez de lui. Deuxièmement, "Ne partez pas d'ici", ou spécifiquement n'utilisez pas de déclencheurs. Il va fondamentalement forcer le passage au traitement au niveau des lignes si les déclencheurs vont se déclencher pour chaque ligne. Mieux vaut mettre la logique dans une procédure stockée que vous appelez. Vous avez alors un début (où vous validez les entrées) et une fin et un chemin logique tout au long. Ils sont beaucoup plus faciles à déboguer lorsque vous suivez un chemin. Troisièmement, ne jamais tester une erreur que vous ne savez pas comment gérer. Si vous ne l'attrapez pas, le client reçoit un rapport d'erreur indiquant ce qui s'est passé (message d'erreur) et où (erreur/pile d'appels). Si vous essayez de l'attraper, vous devez savoir quoi faire avec (et si vous ne savez pas la tendance est de l'ignorer - ce qui est mauvais). Enfin, vous ne pouvez pas facilement voir chaque «couche» d'un select. Le plan d'explication vous dira généralement comment ça se passe. v $ session_longops PEUT indiquer ce qu'il est en train de faire. L'événement d'attente actuel PEUT donner des indices sur la table/bloc/ligne sur laquelle il travaille actuellement.

+0

+1 pour mentionner le plan d'explication, et +1 pour "tout le code fonctionne correctement" :) –

+0

Je n'ai pas donné assez d'informations dans mon original.J'ai écrit un déclencheur qui a travaillé sur des inserts simples mais pas multiples, je pense à cause d'un problème d'interblocage. Je pense que j'ai corrigé ce problème, mais pendant qu'il se passait il y avait une "erreur silencieuse" Y at-il un journal ou quelque chose que je peux trouver des informations comme ça? Un autre suivi: comment une procédure stockée finit différente d'un Disons que j'ai une table dans laquelle une source externe place des données, et une autre table dans laquelle je veux placer des données basées sur cette première table, et la garde à jour avec les données actuelles Comment est la procédure stockée> déclencher là –

+0

Il n'y a pas d'erreur silencieuse: soit il commet une erreur, soit il échoue et il recule, soit il réussit mais, très probablement, fait ce que vous lui avez dit de ne pas faire ce que vous voulez qu'il fasse. Déclaration SQL il ya des problèmes de cohérence en lecture qui conduisent souvent à des solutions de contournement complexes et sujettes aux erreurs –

10

Une méthode simple approximative si vous devez déboguer des déclencheurs est d'utiliser DBMS_OUTPUT.

par exemple.

SQL> CREATE OR REPLACE TRIGGER mytrigger 
    BEFORE UPDATE ON mytable 
    FOR EACH ROW 
    ... 
    BEGIN 
     DBMS_OUTPUT.put_line('mytrigger STARTING'); 
     ... do some logic ... 
     DBMS_OUTPUT.put_line('old=' || :OLD.mycolumn); 
     DBMS_OUTPUT.put_line('new=' || :NEW.mycolumn); 
     DBMS_OUTPUT.put_line('mytrigger FINISHED'); 
    END; 
    /

SQL> SET SERVEROUT ON 
SQL> UPDATE mytable SET mycolumn = mycolumn + 1; 
2 rows updated. 

mytrigger STARTING 
old=10 
new=11 
mytrigger FINISHED 
mytrigger STARTING 
old=20 
new=21 
mytrigger FINISHED 
+0

Bonne information, merci. –

1

application J'utilise un programme de quête appelé TOAD disponible à www.quest.com/toad/toad-for-oracle.aspx.

Comme mentionné ci-dessus, DBMS_OUTPUT est très pratique. Dans votre éditeur, assurez-vous d'activer la fenêtre Sortie.

PL/SQL fonctionne sur des "blocs" de code et vous pouvez l'attraper avec un mot clé EXCEPTION.

(S'il vous plaît pardonnez mon formatage, pas sûr comment formater pour le web)

DECLARE 
    C_DATE_FORMAT VARCHAR2(20) := 'DD-Mon-YYYY'; 
    C_TIME_FORMAT VARCHAR2(20) := 'HH24:MI:SS'; 
    C_NOT_IMPLEMENTED_CODE CONSTANT NUMBER(5) := -20200; 
    C_NOT_IMPLEMENTED_MESSAGE CONSTANT VARCHAR2(255) := 'Not implemented'; 
    not_implemented EXCEPTION; -- user defined exception 
BEGIN 
    --RAISE not_implemented; -- raise user defined exception 
    RAISE_APPLICATION_ERROR(C_NOT_IMPLEMENTED_CODE, C_NOT_IMPLEMENTED_MESSAGE); -- user defined exception 
EXCEPTION -- exception block 
    WHEN not_implemented THEN -- catch not_implemented exception 
     DBMS_OUTPUT.PUT_LINE('Error: Not implemented'); 
    WHEN OTHERS THEN -- catch all other exceptions 
     DBMS_OUTPUT.PUT_LINE('Error occured.'); 
     DBMS_OUTPUT.PUT_LINE('Date: ' || TO_CHAR(SYSDATE, C_DATE_FORMAT)); 
     DBMS_OUTPUT.PUT_LINE('Time: ' || TO_CHAR(SYSDATE, C_TIME_FORMAT)); 
     DBMS_OUTPUT.PUT_LINE('Error code: ' || SQLCODE); 
     DBMS_OUTPUT.PUT_LINE('Error message: ' || SQLERRM); --deal with error 
     RAISE; -- raise to calling object 
END; 
0

Il y a aussi un bon outil Oracle debugger dans dbForge Studio pour Oracle avec exécution de code étape par étape, points d'arrêt, pile d'appels, montres, mécanisme d'évaluation des variables pour les fonctions stockées Oracle et automatisation du débogage des procédures.