2011-09-08 13 views
6

私はかなり時間がかかるPL/SQLブロックを使用して、分子構造からフィンガープリントを作成しています。 SQL * Plusコンソールに出力を出力して、処理された構造の数をフィードバックしたいと思います。私はこれを行うことができます長期実行PL/SQLブロックの監視

しかし、いつも新しい行が書かれています。私はその行を上書きしたい。

たとえば、現在以下のようになっています。

Structure x of y processed 
Structure x of y processed 
Structure x of y processed 
Structure x of y processed 

最終的に私は何千もの構造レコードを処理しているため、バッファをいっぱいにします。

最後の出力行を上書きする方法はありますか?

答えて

15

DBMS_OUTPUTを使用すると、PL/SQLブロック全体が完了するまで何も表示されず、現在バッファにあるすべてのデータが表示されます。したがって、進行中のステータスを提供する適切な方法ではありません。

一方、実行中のコードを監視するために特別に設計されたDBMS_APPLICATION_INFOパッケージが提供されています。たとえば、

SELECT opname, 
     target_desc, 
     sofar, 
     totalwork, 
     units, 
     elapsed_seconds, 
     time_remaining 
    FROM v$session_longops 
WHERE opname = 'Processing of Molecular Structures'; 
+1

+1、素敵なテンプレートの例。 – DCookie

0

私はあなたができるとは思わないV$SESSION_LONGOPSビューを照会することにより、あなたはその後、monitory進歩をすることができ、別のSQL * Plusセッションから

CREATE PROCEDURE process_structures 
AS 
    <<other variable declarations>> 

    rindex BINARY_INTEGER; 
    slno  BINARY_INTEGER; 
    totalwork NUMBER := y; -- Total number of structures 
    worksofar NUMBER := 0; -- Number of structures processed 
BEGIN 
    rindex := dbms_application_info.set_session_longops_nohint; 

    FOR i IN (<<select structures to process>>) 
    LOOP 
    worksofar := worksofar + 1; 
    dbms_application_info.set_session_longops(
     rindex  => rindex, 
     slno  => slno, 
     op_name  => 'Processing of Molecular Structures', 
     sofar  => worksofar , 
     totalwork => totalwork, 
     target_desc => 'Some description', 
     units  => 'structures'); 
    <<process your structure with your existing code>> 
    END LOOP; 
END; 

ような何かを行うことができます。私がdbms_outputを理解する限り、それはちょうどそのようには動作しません。

putを使用して、何かが起こっていることを知るために1000ドットごとに1つのドットと改行をエコーすることをお勧めします。

1

名前付きパイプにメッセージを送信し、別のプロセスでパイプからメッセージを読み取ることもできます。

procedure sendmessage(p_pipename varchar2 
         ,p_message varchar2) is 
     s number(15); 
    begin 
     begin 
     sys.dbms_pipe.pack_message(p_message); 
     exception 
     when others then 
      sys.dbms_pipe.reset_buffer; 
     end; 

     s := sys.dbms_pipe.send_message(p_pipename, 0); 

     if s = 1 
     then 
     sys.dbms_pipe.purge(p_pipename); 
     end if; 
    end; 


    function receivemessage(p_pipename varchar2 
          ,p_timeout integer) return varchar2 is 
     n number(15); 
     chr varchar2(200); 
    begin 
     n := sys.dbms_pipe.receive_message(p_pipename, p_timeout); 

     if n = 1 
     then 
     return null; 
     end if; 

     sys.dbms_pipe.unpack_message(chr); 
     return(chr); 
    end; 
関連する問題