人為的無限迴圈即停止方法
有一些程式,比如系統監控工具,就應該是永遠執行。這種情況下,就會需要人為的無限迴圈:
loop
data_gathering_procedure;
end loop;
由於持續的執行對cpu資源消耗嚴重,為了避免資源耗費殆盡,病保證資料收集過程儘可能有效的執行,
所以需要迴圈在執行中適當的暫停。
loop
data_gathering_procedure;
dbms_lock.sleep(10) ; //10秒內不作任何事情
end loop;
當然 ,那麼我們又如何結束這種無限的迴圈呢?通常我們都是以儲存過程形式執行,即便殺掉前臺程序也不會終止後臺程序。我們可以使用alter system kill session,但在某些版本的oracle中這個命令並不會殺掉一個卡在迴圈中的會話。
所以我們必須求助於作業系統的工具了,比如unix/linux平臺的kill以及windows的orakill.exe.這些工具需要知道oracle的系統程序的ID,在V$SSEION和V$PROCESS中很容易查出。
當然我們還有更好的方法解決這個問題,在迴圈中插入一個“命令直譯器”,然後通過資料庫內建的程序間通訊機制來發送命令即資料庫通道。
declare
pipename constant varchar2(12):='signaler';
result integer;
pipebuf varchar2(64);
begin
/* 建立一個指定名字的私有管道*/
result:=dbms_pipe.create_pipe(pipename);
loop
data_gathering_procedure;
dbms_lock.sleep(10);
/*檢查管道是否有資訊*/
if dbms_pipe.receive_message(pipename ,0)=0
then
dbms_pipe.unpack_message(pipebuf);
exit when pipebuf='stop';
end if;
end loop;
end;
現在可以構造一個簡單地夥伴程式,這個程式只需要通過在管道中傳送一個‘stop‘就可以終止這個迴圈的執行。
declare
pipename varchar2(12):='signaler';
result integer :=dbms_pipe.create_pipe(pipename);
begin
dbms_pipe.pack_message('stop');
end;