關於在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包體裏面,建議直接添加下面這些腳本,二次簡單封裝一下公用的調試處理包,方便調用: 
例如:


 
  1. CREATE OR REPLACE PACKAGE BODY APPS.XYG_ALBND_PACK_PKG

  2. AS

  3. --===============================================================

  4. -- Debug 處理

  5. --===============================================================

  6. --P_DEBUG_LEVEL:該調試信息的級別

  7. PROCEDURE DEBUGLOG (P_DEBUG_LEVEL IN NUMBER,P_DEBUG_MSG IN VARCHAR2)

  8. IS

  9. BEGIN

  10. XYG_ALD_DEBUG_PKG.DEBUGLOG(' XYG_ALBND_PACK_PKG ',P_DEBUG_LEVEL,P_DEBUG_MSG);

  11. END DEBUGLOG;

  12. --簡化版本,默認該消息的是level=1的

  13. PROCEDURE DEBUGLOG1 (P_DEBUG_MSG IN VARCHAR2)

  14. IS

  15. BEGIN

  16. XYG_ALD_DEBUG_PKG.DEBUGLOG(' XYG_ALBND_PACK_PKG ',1,P_DEBUG_MSG);

  17. END DEBUGLOG1;

  18. ….

  19. 接着,在需要顯示調試消息的地方,直接調用這個函數即可:

  20. 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. ------------------------------

  2. ---1 普通在Toad的output調試樣例:

  3. DECLARE

  4. L_RETCODE NUMBER;

  5. L_ERRBUF VARCHAR2(4000);

  6. BEGIN

  7. FND_PROFILE.PUT('XYG_ALD_DEBUG_LEVEL',1);

  8. FND_PROFILE.PUT('XYG_ALD_DEBUG_TYPE','DBMS_OUTPUT');

  9. XYG_ALBND_PACK_PKG.AUTO_CREATE_PACK(

  10. 'PO_HEADERS_ALL'

  11. ,2579287

  12. ,SYSDATE

  13. ,5954

  14. ,'NORMAL'

  15. ,l_retcode

  16. ,l_errbuf

  17. );

  18. DBMS_OUTPUT.PUT_LINE(L_RETCODE||'-'||L_ERRBUF);

  19. END;

  20.  
  21. ------------------------------

  22. ---2 調試結果文件輸出樣例:

  23. DECLARE

  24. L_RETCODE NUMBER;

  25. L_ERRBUF VARCHAR2(4000);

  26. BEGIN

  27. FND_PROFILE.PUT('XYG_ALD_DEBUG_LEVEL',2);

  28. FND_PROFILE.PUT('XYG_ALD_DEBUG_TYPE','FILE_DEBUGLOG');

  29. FND_PROFILE.PUT('XYG_ALD_DEBUG_FILE'

  30. ,'/oracle/vis/apps/apps_st/appl/attchment/12.0.0/BATCH_UPLOAD_TEMP/SAMT_TEST001.log');

  31. XYG_ALBND_PACK_PKG.AUTO_CREATE_PACK(

  32. 'PO_HEADERS_ALL'

  33. ,2579287

  34. ,SYSDATE

  35. ,5954

  36. ,'NORMAL'

  37. ,l_retcode

  38. ,l_errbuf

  39. );

  40. DBMS_OUTPUT.PUT_LINE(L_RETCODE||'-'||L_ERRBUF);

  41. END;

  42.  
  43. --查看文件的路徑

  44. SELECT FND_PROFILE.VALUE('XYG_ALD_DEBUG_FILE') FROM DUAL

  45.  
  46. ------------------------------

  47. --3 如果用數據輸出的

  48. DECLARE

  49. L_RETCODE NUMBER;

  50. L_ERRBUF VARCHAR2(4000);

  51. BEGIN

  52. FND_PROFILE.PUT('XYG_ALD_DEBUG_LEVEL',2);

  53. FND_PROFILE.PUT('XYG_ALD_DEBUG_TYPE','DATA_DEBUGLOG');

  54. XYG_ALBND_PACK_PKG.AUTO_CREATE_PACK(

  55. 'PO_HEADERS_ALL'

  56. ,2579287

  57. ,SYSDATE

  58. ,5954

  59. ,'NORMAL'

  60. ,l_retcode

  61. ,l_errbuf

  62. );

  63. DBMS_OUTPUT.PUT_LINE(L_RETCODE||'-'||L_ERRBUF);

  64. END;

  65. ---查看調試信息:

  66. select to_char(systimestamp, 'yyyy-mm-dd hh24:mi:ss:ff3') debug_time,session_id,module||'[---]'||message_text

  67. from fnd_log_messages

  68. where timestamp > sysdate-1

  69. and session_id=userenv('SESSIONID')

  70. 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

好文要頂 關注我 收藏該文  

sumsen
關注 - 5
粉絲 - 21

+加關注

https://www.cnblogs.com/sumsen/archive/2012/06/13/2547512.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章