今天一个朋友问我如何监测一个PL/SQL的运行状况,这里简单介绍几种方法。
介绍最简单的INSERT的方法。
他们的问题是执行下面的PL/SQL代码:
SQL> SET SERVEROUT ON
SQL> BEGIN
2 DBMS_OUTPUT.PUT_LINE('A');
3 DBMS_LOCK.SLEEP(10);
4 DBMS_OUTPUT.PUT_LINE('B');
5 DBMS_LOCK.SLEEP(10);
6 DBMS_OUTPUT.PUT_LINE('C');
7 END;
8 /
A
B
C
PL/SQL过程已成功完成。
他们希望在PL/SQL代码运行一开始就得到A,运行10秒后,得到B,最后运行完成的时候,得到C。
但是,DBMS_OUTPUT包的调用是发生在PL/SQL代码结束之后的,也就是说,不可能在PL/SQL运行的过程中分批的得多DBMS_OUTPUT的输出结果,最终的输出结果是A、B、C同时输出。
其实解决这个问题的方法很多,最简单的方法是通过INSERT就能解决这个问题。
SQL> CREATE TABLE T_RECORD
2 (STR VARCHAR2(10),
3 TIME DATE);
表已创建。
SQL> BEGIN
2 INSERT INTO T_RECORD VALUES ('A', SYSDATE);
3 COMMIT;
4 DBMS_LOCK.SLEEP(10);
5 INSERT INTO T_RECORD VALUES ('B', SYSDATE);
6 COMMIT;
7 DBMS_LOCK.SLEEP(10);
8 INSERT INTO T_RECORD VALUES ('C', SYSDATE);
9 COMMIT;
10 END;
11 /
PL/SQL过程已成功完成。
这时通过另一个会话就可以时刻检查会话执行到哪个步骤了:
SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
会话已更改。
SQL> SELECT * FROM T_RECORD;
STR TIME
---------- -------------------
A 2010-04-26 16:37:18
SQL> SELECT * FROM T_RECORD;
STR TIME
---------- -------------------
A 2010-04-26 16:37:18
SQL> SELECT * FROM T_RECORD;
STR TIME
---------- -------------------
A 2010-04-26 16:37:18
B 2010-04-26 16:37:28
SQL> SELECT * FROM T_RECORD;
STR TIME
---------- -------------------
A 2010-04-26 16:37:18
B 2010-04-26 16:37:28
SQL> SELECT * FROM T_RECORD;
STR TIME
---------- -------------------
A 2010-04-26 16:37:18
B 2010-04-26 16:37:28
C 2010-04-26 16:37:39
当然这种方法的前提是PL/SQL中可以提交,如果整个PL/SQL代码是一个完整的事务,或者COMMIT是根据业务需要,那么就不能采用这个方法。需要简单的变通一下,利用自治事务的方式:
SQL> TRUNCATE TABLE T_RECORD;
表已截掉。
SQL> CREATE OR REPLACE PROCEDURE P_RECORD (P_STR IN VARCHAR2) AS
2 PRAGMA AUTONOMOUS_TRANSACTION;
3 BEGIN
4 INSERT INTO T_RECORD VALUES (P_STR, SYSDATE);
5 COMMIT;
6 END;
7 /
过程已创建。
SQL> BEGIN
2 P_RECORD('A');
3 DBMS_LOCK.SLEEP(10);
4 P_RECORD('B');
5 DBMS_LOCK.SLEEP(10);
6 P_RECORD('C');
7 END;
8 /
PL/SQL过程已成功完成。
在另一个会话中可以检查会话运行的状态:
SQL> SELECT * FROM T_RECORD;
STR TIME
---------- -------------------
A 2010-04-26 16:49:59
SQL> SELECT * FROM T_RECORD;
STR TIME
---------- -------------------
A 2010-04-26 16:49:59
SQL> SELECT * FROM T_RECORD;
STR TIME
---------- -------------------
A 2010-04-26 16:49:59
B 2010-04-26 16:50:09
SQL> SELECT * FROM T_RECORD;
STR TIME
---------- -------------------
A 2010-04-26 16:49:59
B 2010-04-26 16:50:09
SQL> SELECT * FROM T_RECORD;
STR TIME
---------- -------------------
A 2010-04-26 16:49:59
B 2010-04-26 16:50:09
C 2010-04-26 16:50:20
这种方法的最大优点就是简单,编码量也很小,需要的辅助对象仅仅是一张表和一个存储过程而已。
总机:(010)-88589926,88589826,88587026 QQ讨论群:243729577 182441349 邮箱:cuug_bj@cuug.com
通信地址:北京市海淀区紫竹院路98号北京化工大学科技园609室(CUUG)邮政编码:100089
中国UNIX用户协会 Copyright 2010 ALL Rights Reserved 北京神脑资讯技术有限公司
京ICP备11008061号 京公网安备110108006275号