7

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

ただし、それが呼び出されるたびに改行が書き込まれます。行を上書きしたい。

たとえば、現在私は以下を持っています。

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

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

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

4

3 に答える 3

16

使用DBMS_OUTPUTとは、PL / SQLブロック全体が完了するまで、SQL * Plusは何も表示せず、その後、現在バッファにあるすべてのデータを表示することを意味します。したがって、継続的なステータスを提供するための適切な方法ではありません。

一方、Oracleは、実行中のコードの監視に役立つように特別に設計されたパッケージDBMS_APPLICATION_INFOを提供しています。たとえば、次のようなことができます

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;

V$SESSION_LONGOPS別のSQL*Plusセッションから、ビューにクエリを実行して進行状況を監視できます。

SELECT opname,
       target_desc,
       sofar,
       totalwork,
       units,
       elapsed_seconds,
       time_remaining
  FROM v$session_longops
 WHERE opname = 'Processing of Molecular Structures';
于 2011-09-08T15:50:11.533 に答える
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;
于 2011-09-12T10:44:54.537 に答える
0

私はあなたができるとは思わない。私がdbms_outputを理解している限り、それはそのようには機能しません。

putを使用して、1000程度のエントリごとに1つのドットと改行をエコーし​​て、何かが起こっていることを確認し、テーブルに書き込んだり、現在の位置をシーケンスしたりして、知りたい場合に確認できるようにすることをお勧めします。

于 2011-09-08T15:51:41.097 に答える