關於在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.csdn.net/detail/samt007/9806450
https://blog.csdn.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