2011-09-08 9 views
6

Ho un blocco PL/SQL abbastanza impegnativo che crea fingerprint da strutture molecolari. Vorrei stampare l'output sulla console SQL * Plus per fornire feedback su quante strutture sono state elaborate. Posso farlo con dbms_output.put_lineMonitoraggio del blocco PL/SQL con esecuzione prolungata

Tuttavia ogni volta che viene chiamata una nuova riga viene scritta. Voglio sovrascrivere la linea.

Ad esempio, attualmente ho il sotto.

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

Eventualmente riempio il buffer poiché sto trattando migliaia di record di struttura.

C'è un metodo che posso usare che sovrascriverà solo l'ultima linea di uscita?

risposta

15

L'utilizzo di DBMS_OUTPUT indica che SQL * Plus non visualizzerà nulla fino a quando l'intero blocco PL/SQL non sarà completo e visualizzerà tutti i dati attualmente nel buffer. Non è, quindi, un modo appropriato per fornire uno status continuo.

D'altra parte, Oracle fornisce un pacchetto DBMS_APPLICATION_INFO specificamente progettato per aiutare a monitorare il codice in esecuzione. Ad esempio, si potrebbe fare qualcosa di simile

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; 

Da una sessione SQL * Plus separata, si può progredire poi monitory interrogando la vista V$SESSION_LONGOPS

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

+1, bel esempio di modello. – DCookie

0

Non credo che si può. Per quanto ho capito, dbms_output non funziona in questo modo.

Vi consiglio di utilizzare put per echo un singolo punto e una nuova riga ogni 1000 o più voci per vedere che qualcosa sta accadendo e scrivere in una tabella o sequenza la posizione corrente in modo da poter dare un'occhiata se volete sapere.

1

È inoltre possibile inviare messaggi a una pipe denominata e fare in modo che un altro processo legga il messaggio dalla pipe.

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; 
Problemi correlati