2010-09-17 11 views
6

Ich weiß nicht, wo Fehlerinformationen gehen, wenn ein Trigger nicht richtig funktioniert.Oracle Debugging-Techniken

Mein Werkzeug zum Schreiben von Triggern ist Oracle Sql Developer Tool, und meine Kenntnisse darüber, wie man es debuggt, ist so gut wie nicht existent. Welche Hinweise gibt es, um nützliche Informationen über Dinge zu finden, die "hinter den Kulissen" passieren? Gibt es auch bessere Tools, die Sql Developer zum Verbinden, Testen, Debuggen usw.?

Meine Methode war bisher, etwas zu schreiben (ein Trigger zum Beispiel), es mit einzelnen Einfügungen/Löschungen zu testen, und hoffe dann, dass es von ihnen aus funktioniert. Gibt es bessere Möglichkeiten, um sicherzustellen, dass es genau das tut, was Sie wollen? Zum Beispiel, mit einer Select-Anweisung, gibt es sowieso (in einem Debug-Zustand oder etwas) jede Ebene der Auswahl und wie schneidet er die Ergebnisse ab? Irgendwelche Tipps sehr geschätzt.

Antwort

12

Erstens funktioniert der gesamte Code korrekt. Es tut einfach nicht, was Sie erwartet haben.

Zweitens, "nicht von hier starten", oder insbesondere keine Trigger verwenden. Es wird im Grunde genommen die Umschaltung auf die Verarbeitung auf Zeilenebene erzwingen, wenn Trigger für jede Zeile ausgelöst werden. Besser, die Logik in eine gespeicherte Prozedur zu bringen, die Sie aufrufen. Sie haben dann einen Anfang (wo Sie Eingaben validieren) und ein Ende und einen logischen Pfad den ganzen Weg. Sie sind viel einfacher zu debuggen, wenn Sie einem Pfad folgen.

Drei, Testen Sie nie für einen Fehler, mit dem Sie nicht umgehen können. Wenn Sie es nicht abfangen, blubbert es zu dem Client, der einen Fehlerbericht erhält, der sagt, was schief gelaufen ist (Fehlermeldung) und wo (dh der Fehler/Aufrufstapel). Wenn Sie versuchen, es zu fangen, müssen Sie wissen, was damit zu tun ist (und wenn Sie nicht wissen, dass die Tendenz es ignoriert - was SCHLECHT ist).

Schließlich können Sie nicht jede 'Schicht' eines Select leicht sehen. Der Erklärungs-Plan wird Ihnen im Allgemeinen sagen, wie es um Dinge geht. v $ session_longops KANN angeben, was es gerade macht. Das aktuelle Warteereignis MAY gibt Hinweise darauf, an welcher Tabelle/Block/Zeile es gerade arbeitet.

+0

+1 für Erwähnung erklären Plan, und +1 für "alle Code funktioniert richtig" :) –

+0

Ich habe nicht genug Informationen in meinem Original geben.Ich habe einen Trigger geschrieben, der an einzelnen Einfügungen gearbeitet hat, aber nicht an mehreren, denke ich wegen eines Deadlock-Problems. Ich denke, dass ich dieses Problem behoben habe, aber während es lief, war es ein "stiller Fehler". Gibt es ein Protokoll oder etwas, in dem ich solche Informationen finden kann? Ein weiteres Follow-up: Wie würde eine gespeicherte Prozedur anders als a sein? trigger? Angenommen, ich habe eine Tabelle, in die eine externe Quelle Daten einfügt, und eine andere Tabelle, in die ich Daten basierend auf dieser ersten Tabelle einbetten möchte, und sie mit aktuellen Daten aktualisieren. Wie wird Stored Procedure> dort ausgelöst? –

+0

Dort Es sind keine stummen Fehler, entweder Fehler, Fehler und Rollbacks, oder es ist erfolgreich, aber möglicherweise tut es das, was Sie ihm gesagt haben, nicht das, was Sie wollen, weil die Trigger auf Zeilenebene im Verlauf eines SQL-Anweisung gibt es lesen Konsistenzprobleme, die oft zu komplexen und fehleranfälligen Problemumgehungen führen –

10

Eine grobe und einfache Methode, wenn Sie Trigger debuggen müssen, ist DBMS_OUTPUT zu verwenden.

z.B.

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

Gute Info, danke. –

1

Anwendung Ich benutze ein Programm von Quest namens TOAD bei www.quest.com/toad/toad-for-oracle.aspx zur Verfügung.

Wie oben erwähnt, ist DBMS_OUTPUT sehr praktisch. Stellen Sie in Ihrem Editor sicher, dass Sie das Ausgabefenster aktivieren.

PL/SQL arbeitet an "Blöcken" Code und Sie können es mit einem Schlüsselwort EXCEPTION abfangen.

(verzeihen Sie bitte meine Formatierung, nicht sicher, wie für Web-Format)

hat
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

Es ist auch ein gutes Oracle debugger Werkzeug in dbForge Studio for Oracle mit schrittweiser Code-Ausführung, Breakpoints, einem Call-Stack, Watches, einem Variablen-Evaluierungsmechanismus für Oracle-gespeicherte Funktionen und Prozeduren zum Debuggen von Automation.