关于在PLSQL中实现DEBUG调试功能的方法
关于在PLSQL中实现DEBUG调试功能的方法
2017年04月07日 14:27:52 samt007 阅读数:2179 标签: oracle调试plsql 更多
个人分类: Oracle PL/SQL技巧
前言
一个健康的PLSQL,应该都带有一套完整的调试逻辑。特别是那些功能很复杂的PLSQL,就更加有必要具备调试功能了。否则,当PLSQL处理数据出现问题的时候,分析(处理)起来会相当的困难。
举个例子,Oracle EBS标准功能的PLSQL(特别是API),如果Oracle没有自带调试功能给我们做看每一步骤的调试结果,单单通过看代码模拟其执行逻辑来找问题,基本上是不可能处理问题的!
当然,我们编写的代码,实际上大部分的都并没有很复杂,所以对调试部分没太高的要求。这里也建议按照实际情况来做。但是一些重要的并且是复杂的功能,还是必须要考虑如何添加调试!
实现调试的办法
现在根据这几年写PLSQL的经验,得出的一套如何在PLSQL中实现调试的方法,特意分享一下。如果有更加好的方法,也可以一起讨论一下!
具体实现办法:
1 首先,统一新建3个客户化的Profile配置来实现调试功能的开关:
CUX:程序调试级别
设置调试的级别。这里是仿照标准功能的调试逻辑来做的一个设定。作用就是是否启用调试,以及调试的数据输出的明细级别!
具体:
XYG_ALD_DEBUG_LEVEL:设置查看调试消息的级别
0:不查看调试(默认值)
1:查看调试程序主要消息级别=1的消息
2:查看消息的调试级别<=2的信息
3:查看消息的调试级别<=3的信息
4:查看消息的调试级别<=4的信息
5:查看消息的调试级别<=5的信息
举个例子,如果我的调试消息设置是:调试级别3,调试显示3的信息。
则当XYG_ALD_DEBUG_LEVEL级别是2的时候,这个3的调试信息是不会显示的。
当XYG_ALD_DEBUG_LEVEL级别大于等于3的时候,这个消息才会显示出来!
具体可以自己写一个例子来理解。
CUX:程序调试方式
就是调试结果显示的方式。
一般来说有下面几种方式:
调试方式XYG_ALD_DEBUG_TYPE:
DBMS_OUTPUT直接输出
FILE_DEBUGLOG文档输出
REQUEST_DEBUGLOG请求日志输出
DATA_DEBUGLOG表格数据输出
DBMS_OUTPUT:这个不用多说了,实际上就是调用DBMS_OUTPUT.PUT_LINE在开发工具直接显示消息。
FILE_DEBUGLOG:这个很重要!不过要配合一些额外的定义,才可以看到这种输出的结果。这种方式的调试结果以文件的形式存在服务器里面。适合那种超大数据量输出的调试信息。
REQUEST_DEBUGLOG:如果PLSQL是在请求中调用的话,可以考虑用这种方式查看调试信息。调试信息会直接显示在请求的日志里面。
DATA_DEBUGLOG表格数据输出:就是将调试的结果输出在fnd_log_messages表。和标准功能的保持一致!
CUX:程序调试文件
结合调试方式= FILE_DEBUGLOG文档输出使用。
就是定义调试结果产生的文件是什么。
注意:如果这个设定为空,则默认文件= XYG_PUB_AUTOMAIL_PKG.XYG_DF_UTL_FILE_DIR||’/’||userenv(‘SESSIONID’)||’.log’
2 PLSQL里面如何使用调试的方法:
首先,在要添加调试逻辑的PKG包体里面,建议直接添加下面这些脚本,二次简单封装一下公用的调试处理包,方便调用:
例如:
-
CREATE OR REPLACE PACKAGE BODY APPS.XYG_ALBND_PACK_PKG
-
AS
-
--===============================================================
-
-- Debug 处理
-
--===============================================================
-
--P_DEBUG_LEVEL:该调试信息的级别
-
PROCEDURE DEBUGLOG (P_DEBUG_LEVEL IN NUMBER,P_DEBUG_MSG IN VARCHAR2)
-
IS
-
BEGIN
-
XYG_ALD_DEBUG_PKG.DEBUGLOG(' XYG_ALBND_PACK_PKG ',P_DEBUG_LEVEL,P_DEBUG_MSG);
-
END DEBUGLOG;
-
--简化版本,默认该消息的是level=1的
-
PROCEDURE DEBUGLOG1 (P_DEBUG_MSG IN VARCHAR2)
-
IS
-
BEGIN
-
XYG_ALD_DEBUG_PKG.DEBUGLOG(' XYG_ALBND_PACK_PKG ',1,P_DEBUG_MSG);
-
END DEBUGLOG1;
-
….
-
接着,在需要显示调试消息的地方,直接调用这个函数即可:
-
DEBUGLOG(1,'GENERATE_XXXXXXXXXXXXX(+)'); 或者:DEBUGLOG1('GENERATE_XXXXXXXXXXXXX(+)');
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
需要注意的是,DEBUGLOG的第一个参数是该消息的显示级别。换句话说,就是你希望这个消息在什么级别显示它!
举个例子,如果设置为3,则消息基本是3级,当设置显示的消息级别大于等于3的时候,该消息会显示。
3 程序如何查看调试的结果:
-
------------------------------
-
---1 普通在Toad的output调试样例:
-
DECLARE
-
L_RETCODE NUMBER;
-
L_ERRBUF VARCHAR2(4000);
-
BEGIN
-
FND_PROFILE.PUT('XYG_ALD_DEBUG_LEVEL',1);
-
FND_PROFILE.PUT('XYG_ALD_DEBUG_TYPE','DBMS_OUTPUT');
-
XYG_ALBND_PACK_PKG.AUTO_CREATE_PACK(
-
'PO_HEADERS_ALL'
-
,2579287
-
,SYSDATE
-
,5954
-
,'NORMAL'
-
,l_retcode
-
,l_errbuf
-
);
-
DBMS_OUTPUT.PUT_LINE(L_RETCODE||'-'||L_ERRBUF);
-
END;
-
------------------------------
-
---2 调试结果文件输出样例:
-
DECLARE
-
L_RETCODE NUMBER;
-
L_ERRBUF VARCHAR2(4000);
-
BEGIN
-
FND_PROFILE.PUT('XYG_ALD_DEBUG_LEVEL',2);
-
FND_PROFILE.PUT('XYG_ALD_DEBUG_TYPE','FILE_DEBUGLOG');
-
FND_PROFILE.PUT('XYG_ALD_DEBUG_FILE'
-
,'/oracle/vis/apps/apps_st/appl/attchment/12.0.0/BATCH_UPLOAD_TEMP/SAMT_TEST001.log');
-
XYG_ALBND_PACK_PKG.AUTO_CREATE_PACK(
-
'PO_HEADERS_ALL'
-
,2579287
-
,SYSDATE
-
,5954
-
,'NORMAL'
-
,l_retcode
-
,l_errbuf
-
);
-
DBMS_OUTPUT.PUT_LINE(L_RETCODE||'-'||L_ERRBUF);
-
END;
-
--查看文件的路径
-
SELECT FND_PROFILE.VALUE('XYG_ALD_DEBUG_FILE') FROM DUAL
-
------------------------------
-
--3 如果用数据输出的
-
DECLARE
-
L_RETCODE NUMBER;
-
L_ERRBUF VARCHAR2(4000);
-
BEGIN
-
FND_PROFILE.PUT('XYG_ALD_DEBUG_LEVEL',2);
-
FND_PROFILE.PUT('XYG_ALD_DEBUG_TYPE','DATA_DEBUGLOG');
-
XYG_ALBND_PACK_PKG.AUTO_CREATE_PACK(
-
'PO_HEADERS_ALL'
-
,2579287
-
,SYSDATE
-
,5954
-
,'NORMAL'
-
,l_retcode
-
,l_errbuf
-
);
-
DBMS_OUTPUT.PUT_LINE(L_RETCODE||'-'||L_ERRBUF);
-
END;
-
---查看调试信息:
-
select to_char(systimestamp, 'yyyy-mm-dd hh24:mi:ss:ff3') debug_time,session_id,module||'[---]'||message_text
-
from fnd_log_messages
-
where timestamp > sysdate-1
-
and session_id=userenv('SESSIONID')
-
order by LOG_SEQUENCE;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
完工!就是这么的简单,让您写的PLSQL就拥有了完整的而且有非常好扩展性的调试功能!
文档下载以及源代码下载的链接:
http://download.****.net/detail/samt007/9806450
https://blog.****.net/samt007/article/details/69537289
试玩了plsql中test窗口declare声明变量|lpad函数||plsql sql command test window区别|
在这里先感谢一下itpub高手的帖子答复
Q:
看到的oracle中的for循环or i in 1..100 loop,i都是从1,2,3这样递增的,可是我这里需要i从01,02,03这样递增,9开始是09,10,11,12.
请问这样的for循环怎么写。
具体问题可见http://www.itpub.net/thread-1620912-1-1.html,我想在触发器中加入循环变量,精简我的触发器长度。
ps:我是新手,谢谢大家的帮助
A:
lpad('tech', 7); would return ' tech'
lpad('tech', 2); would return 'te'
lpad('tech', 8, '0'); would return '0000tech'
lpad('tech on the net', 15, 'z'); would return 'tech on the net'
lpad('tech on the net', 16, 'z'); would return 'ztech on the net'
每次看到itpub的答复都很激动,一个恢复解决问题。
lpad函数说明
语法格式如下:
lpad( string, padded_length, [ pad_string ] )
string
准备被填充的字符串;
padded_length
填充之后的字符串长度,也就是该函数返回的字符串长度,如果这个数量比原字符串的长度要短,lpad函数将会把字符串截取成从左到右的n个字符;
pad_string
填充字符串,是个可选参数,这个字符串是要粘贴到string的左边,如果这个参数未写,lpad函数将会在string的左边粘贴空格。
下面说plsq中的块。
经常看到有人和书上直接写declare,也不在触发器或者存储过程中,可是照样使用,比如:http://zhidao.baidu.com/question/113921713.html
1,我刚开始直接在plsql中的查询窗口sql window使用,报错:
13:51更新:
sql windows窗口也是可以显示的,在第二列就是output,仅仅select不行
2,想到在测试窗口test window,通过(需要点击左上角的start debugger按钮,然后点击run)
-- Created on 2012-6-13 by DELL declare -- Local variables here i number; begin -- Test statements here for i in 1..100 loop dbms_output.put_line(lpad(i,2,'0')); end loop; end;
下面是结果
拓展:
1 Command window实现了SQL*Plus的所有功能,允许运行sql*plus命令,sql命令,sql脚本。
2 SQL window用于执行sql语句,显示sql输出,执行统计信息。(测试sql语句,查看表中的数据,更新数据)
例如 desc table(查看表结构)不能在SQL window中执行,必须在Command window中才能执行。
3 Program window中创建一个存储过程(或者直接在plsql左边对应的procedures和trigger右键新建),如下:
create or replace procedure TEST is begin DBMS_SESSION.set_nls('NLS_DATE_FORMAT','''YYYY-MM-DD HH24:MI:SS'''); DBMS_OUTPUT.PUT_LINE('HelloWorld!'); DBMS_OUTPUT.put_line(SYSDATE); end TEST;
需要注意,SET_NLS的第二个参数VALUE
输入的值除了需要的格式外,还需要包含引号,否则会引发错误(选项缺失或无效)
在Command window中执行(或者在Test window中测试),如下:
set serveroutput on
exec TEST();
或者begin
2 test();
3 end;
4 / ......
分类: ORACLE
https://www.cnblogs.com/sumsen/archive/2012/06/13/2547512.html