昨天一个朋友问我如何监测一个PL/SQL的运行状况,这里简单介绍几种方法。


介绍更专业的DBMS_PIPE实现方式。


如果觉得DBMS_APPLICATION_INFO包还不够专业,这里再介绍一篇更加PROFESSIONAL的解决方案,通过DBMS_PIPE实现进程间通信。


利用这种方法,进行操作的PL/SQL过程可以通过管道发送消息给接收进程。下面给出一个最简单的例子:


SQL> CREATE TABLE T_RECORD


 2  (STR VARCHAR2(30),


 3  TIME DATE);


表已创建。


建立一个记录表。


随后,负责监测的进程启动一个PIPE,然后定时检测PIPE中是否存在数据:


SQL> DECLARE


 2     V_RETURN NUMBER;


 3     V_STR VARCHAR2(32767);


 4  BEGIN


 5     V_RETURN := DBMS_PIPE.CREATE_PIPE('P_TEST');


 6     WHILE (V_RETURN = 0) LOOP


 7             V_RETURN := DBMS_PIPE.RECEIVE_MESSAGE('P_TEST', 360);


 8             IF V_RETURN = 0 THEN


 9                     DBMS_PIPE.UNPACK_MESSAGE(V_STR);


10                     INSERT INTO T_RECORD VALUES (V_STR, SYSDATE);


11             END IF;


12     END LOOP;


13     V_RETURN := DBMS_PIPE.REMOVE_PIPE('P_TEST');


14  END;


15  /


需要注意,正常情况下,很可能这个PL/SQL一直处于监测状态,不过这就需要修改过程使得过程中提交事务。


当前例子为了简单,设置了10分钟的过期时间,确保要监控的PL/SQL发消息的时间间隔小于10分钟。在这10分钟内,在另外的会话运行PL/SQL代码:


SQL> DECLARE


 2     V_STR VARCHAR2(4000) := 'STEP BEGIN';


 3     V_RETURN NUMBER;


 4  BEGIN


 5     DBMS_PIPE.PACK_MESSAGE(V_STR);


 6     V_RETURN := DBMS_PIPE.SEND_MESSAGE('P_TEST');


 7     DBMS_LOCK.SLEEP(60);


 8     V_STR := 'STEP MIDDLE';


 9     DBMS_PIPE.PACK_MESSAGE(V_STR);


10     V_RETURN := DBMS_PIPE.SEND_MESSAGE('P_TEST');


11     DBMS_LOCK.SLEEP(60);


12     V_STR := 'STEP END';


13     DBMS_PIPE.PACK_MESSAGE(V_STR);


14     V_RETURN := DBMS_PIPE.SEND_MESSAGE('P_TEST');


15  END;


16  /


PL/SQL过程已成功完成。


当这个代码运行结束10分钟后,前面监测过程由于超时退出运行,这时检查日志信息:




PL/SQL过程已成功完成。


SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';


会话已更改。


SQL> SELECT * FROM T_RECORD;


STR                            TIME


------------------------------ -------------------


STEP BEGIN                     2010-04-28 16:33:43


STEP MIDDLE                    2010-04-28 16:34:43


STEP END                       2010-04-28 16:35:43


这种方法适用于专门的监测程序。不过DBMS_PIPE包需要额外的授权



oracle视频教程请关注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html