2009-11-13 13 views
19

Ich habe eine Reihe von pl/SQL-Verfahren, die einige Minuten dauern kann. Während ich sie entwickelt habe, habe ich ein paar Druckanweisungen hinzugefügt, um beim Debuggen zu helfen und auch Feedback und Fortschrittsindikatoren zu geben. Anfangs habe ich diese auf kleinen Testsets ausgeführt und die Ausgabe war fast sofort. Jetzt, da ich mit größeren Testsets teste, deren Ausführung einige Minuten in Anspruch nimmt, ist das Drucken auf der Konsole nicht mehr geeignet, da bis zum Ende des Vorgangs nichts gedruckt wird. Ich bin es gewohnt, in Umgebungen zu arbeiten, in denen die Ausgabe nicht gepuffert und sofort gedruckt wird, und einfache Druckanweisungen für einfaches Debugging und Diagnose hinzugefügt werden.Oracle PL/SQL - Tipps für sofortige Ausgabe/Console Drucken

Ist es in pl/sql möglich, die Ausgabe sofort zu drucken (nicht gepuffert)? Wenn nicht, welche Alternativen empfehlen die Leute, um ein ähnliches Ergebnis zu erzielen?

Antwort

17

Sie können eine Prozedur, die Nachrichten an einen Tisch mit einer autonomen Transaktion so etwas wie schreibt:

procedure log (p_message) 
is 
    pragma autonomous_transaction; 
begin 
    insert into message_log (user, datetime, message) 
    values (user, sysdate, p_message); 
    commit; 
end; 

Dann überwachen die Tabelle aus einer anderen Oracle-Sitzung.

+1

Mehr Informationen zu pragma autonomous_transaction http://stackoverflow.com/questions/1335331/autonomousstransaction – caddis

+1

Das sieht gut aus, ich werde es wahrscheinlich heute ausprobieren :) Wie vergleicht es mit dem anderen Vorschlag der Verwendung von Rohren? Was wird einfacher zu sehen und zu überwachen sein? – FrustratedWithFormsDesigner

+0

Ich habe die Pipe-Methode nicht verwendet, daher kann ich dazu nichts sagen. Ein Unterschied zur Tabellenmethode besteht darin, dass die Nachrichten persistent sind. Dies kann ein Vorteil sein, aber es bedeutet auch, dass Sie sie verwalten müssen, damit der Tisch nicht unbegrenzt wächst! –

8

haben wir einen kleinen Trick dafür.

können Sie DBMS_APPLICATION_INFO.set_client_info ("einige Informationen hier"); Erstellen von Variablen und Ersetzen der Zeichenfolge in "".

und verwenden Sie die Option client_info aus v $ session, um den Fortschritt zu überwachen.

+0

Ich habe Zugriff auf eine v $ session_longops und v $ session_connect_info und keine von ihnen hat ein client_info Feld. Wäre v $ session_longops genauso gut? – FrustratedWithFormsDesigner

+1

Nein, Sie müssen v $ Sitzungsansicht verwenden. fragen Sie DBA, wenn Sie keinen Zugriff haben. –

1

Generell gibt es zwei Optionen:

  • die Ausgabe senden zu einer Oracle-Tabelle (oder temporäre Tabelle)
  • Schreiben Sie an den (Datenbank-Host) Dateisystem mit UTL_FILE

Wenn Sie Haben Sie keinen Betriebssystemzugriff auf den Datenbankhost, können Sie weiterhin in das Dateisystem dbhost schreiben und eine extern definierte Oracle-Tabelle an die Datei binden, damit sie mit einem SELECT abgefragt werden kann.

1

Es kann von Ihrem Client-Tool abhängen. Ich habe SQL * Plus seit einiger Zeit nicht mehr benutzt, aber wenn ich Prozeduren im PL/SQL Developer debugge, öffne ich ein Befehlsfenster und gebe einen SET SERVEROUTPUT ON Befehl aus. Dann, wenn ich die Prozedur ausführe, zeigt alles, was von DBMS_OUTPUT.PUT_LINE gedruckt wird, sofort an.

Edit: du hast Recht, ich denke, ich sah nur, dass mit größeren Mengen von Ausgaben oder etwas. Jedenfalls habe ich ein wenig online gesucht und bin auf dieses log4plsql gestoßen - könnte nützlich sein.

+0

Ich bin Usign PL/SQL Entwickler, das funktioniert nicht. Die gesamte Ausgabe wird sofort ausgedruckt, wenn das Skript ausgeführt wurde. – FrustratedWithFormsDesigner

1

Eine Alternative ist die Verwendung einer Pipeline-Funktion, die Ihre Protokollinformationen zurückgibt. Sehen Sie hier ein Beispiel: http://berxblog.blogspot.com/2009/01/pipelined-function-vs-dbmsoutput.html Wenn Sie eine Pipeline-Funktion verwenden, müssen Sie keine andere SQLPLUS/Toad/sql-Entwickler-Sitzung verwenden.

+0

Das ist interessant, aber müsste ich meine existierende Funktion nicht ändern, um sie zu pipelinern oder sie möglicherweise in eine Pipeline-Funktion einzubinden? – FrustratedWithFormsDesigner

+0

Natürlich müssen Sie Ihren Code ändern. Wenn Sie es nur in eine Pipeline-Funktion einfügen, hilft es Ihnen nicht, da Sie sofort protokollieren und nicht nur protokollieren möchten, wenn etwas erledigt ist. – tuinstoel

2

Ich habe dbms_pipe für diesen Zweck verwendet. Senden Sie Nachrichten an eine Named Pipe und lesen Sie sie von einer anderen Sitzung. Diese Methode funktioniert möglicherweise nicht in einer RAC-Umgebung, wenn sich die Schreib- und Leseprozesse mit einem anderen Knoten verbinden können.

Alternativ können Sie Nachrichten in eine Tabelle einfügen, indem Sie eine Prozedur verwenden, die mit "pragma autonomous_transaction" in einer eigenen Sitzung ausgeführt wird.Sie können diese Nachrichten von einer anderen Sitzung abfragen

Edit: Ich sehe, dass meine zweite Option bereits erwähnt wurde.

+0

Beide sehen wie interessante Möglichkeiten aus, obwohl ich einen Fehler (wahrscheinlich Berechtigungen bezogen) bekomme, wenn ich versuche, das dbms_pipe-Paket zu verwenden. Was sind die Vor- und Nachteile jedes Ansatzes? Ich weiß nicht viel über Oracle-Pipes, daher bin ich mir nicht sicher, wie ich das beurteilen soll, aber es sieht näher als ich aus, als eine tabellengesteuerte Lösung. – FrustratedWithFormsDesigner

1

Sie können DBMS Pipe und den Pipe Viewer in PL/SQL Developer verwenden, um asynchron alle Informationen abzufangen, wenn sie in die Pipe eingefügt werden.

Achten Sie darauf, nur Dinge in eine Rohrleitung zu legen, wenn jemand sie lesen kann. Andernfalls wird Ihr Anruf fehlschlagen, wenn die Leitung voll ist.

Es gibt auch die Möglichkeit, Ereignisse zu verwenden, PL/SQL Entwickler hat auch einen Ereignismonitor. Und die Dokumente sollten ein Beispiel dafür geben, wie es gemacht wird.

+0

Das sieht gut aus, aber ich bekomme einen Fehler: "Bezeichner 'DBMS_PIPE' muss deklariert werden", ich denke, ich muss mit dem DBA darüber reden. Wahrscheinlich ein Berechtigungsproblem. – FrustratedWithFormsDesigner

0

Eine weitere Option ist, dass Ihr PL/SQL-Aufruf eine Prozedur zum Senden einer E-Mail mit der Protokollnachricht ist. Dies erfordert, dass Ihre Datenbank über E-Mail-Sendefunktionen verfügt, die mit UTL_SMTP hinzugefügt werden können.