用C#实现对Oracle 存储过程/函数/包的调试(附源代码)

Oracle用SYS.DBMS_DEBUG实现对存储过程/函数/包的调试。如果你用DESC SYS.DBMS_DEBUG命令查看它的发现其
成员函数和方法并不是特别多,但是为了实现这个功能却花了我近10天的功夫,因为某些方法或函数的不恰当的调用,
会导致意想不到的问题,如程序挂起。主要参考了Oracle的官方文档:
http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96612/d_debug.htm
http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96612/d_debug2.htm

为了实现调试功能,你要打开两个Oracle连接,一个是执行你要调试语句的targetSession,
另外一个是对其进行调试的debugSession.在调试之前,你需要对你要调试的存储过程/函数/包要重新编译以产生编译信息
ALTER [PROCEDURE | FUNCTION | PACKAGE | TRIGGER | TYPE] <name> COMPILE DEBUG;
ALTER [PACKAGE | TYPE] <name> COMPILE DEBUG BODY;

请看下面的流程图关于目标会话/调试会话需要执行的动作及其相互关系:
o_Oracle%20Debug.gif
启动调试的代码:
 1 None.gif private   void  StartDebug()
 2 ExpandedBlockStart.gifContractedBlock.gif         dot.gif {
 3ContractedSubBlock.gifExpandedSubBlockStart.gif            dot.gif#region            
 4InBlock.gif            this.mStepInto.Enabled = false;            
 5InBlock.gif            this.mStepOver.Enabled = false;
 6InBlock.gif            this.mRun.Enabled = false;            
 7InBlock.gif            this.IsDebuging = true;
 8InBlock.gif            this.MSQL.Document.ReadOnly = true;
 9InBlock.gif            this.btnConfigure.Enabled = false;
10InBlock.gif            this.OutParameterGrid.RowCount = 0;
11InBlock.gif            this.OutDataGrid.DataSource = null;
12ExpandedSubBlockEnd.gif            #endregion

13InBlock.gif
14ContractedSubBlock.gifExpandedSubBlockStart.gif            initialize target session and command#region initialize target session and command    
15InBlock.gif            if(this.targetSession == null)
16ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
17InBlock.gif                string csn = this._connection.GetOleCSNInfo().CSNNoProvider;
18InBlock.gif                targetSession = new OracleConnection(csn +  ";Pooling=false;");                 
19InBlock.gif                targetSession.Open();
20InBlock.gif                //targetSession.
21InBlock.gif                targetCommand = targetSession.CreateCommand();                
22InBlock.gif                targetCommand.CommandText = "begin SYS.DBMS_APPLICATION_INFO.SET_CLIENT_INFO(:id); end;";                
23InBlock.gif                OracleParameter idp  = targetCommand.Parameters.Add("id",OracleType.VarChar,64);
24InBlock.gif                targetClientID = System.Guid.NewGuid().ToString();
25InBlock.gif                idp.Value = targetClientID;
26InBlock.gif                targetCommand.ExecuteNonQuery();
27InBlock.gif                targetCommand.Parameters.Clear();
28ExpandedSubBlockEnd.gif            }

29ExpandedSubBlockEnd.gif            #endregion
 
30InBlock.gif
31ContractedSubBlock.gifExpandedSubBlockStart.gif            initialize debug session and command#region initialize debug session and command
32InBlock.gif            if(this.debugSession == null)
33ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
34InBlock.gif                string csn = this._connection.GetOleCSNInfo().CSNNoProvider;
35InBlock.gif                debugSession = new OracleConnection(csn);
36InBlock.gif                debugCommand = debugSession.CreateCommand();   
37InBlock.gif                debugSession.Open ();                
38ExpandedSubBlockEnd.gif            }

39ExpandedSubBlockEnd.gif            #endregion

40InBlock.gif   
41ContractedSubBlock.gifExpandedSubBlockStart.gif            prepare#region prepare
42InBlock.gif            targetCommand.Parameters.Clear();
43InBlock.gif            if(this.debugID == null)
44ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
45InBlock.gif                targetCommand.CommandText = "alter session set plsql_debug=true";
46InBlock.gif                targetCommand.Parameters.Clear();
47InBlock.gif                targetCommand.ExecuteNonQuery();
48InBlock.gif
49InBlock.gif                //targetCommand.CommandText = "alter procedure TEST compile debug";
50InBlock.gif                //targetCommand.ExecuteNonQuery();
51ExpandedSubBlockEnd.gif                #endregion
 
52InBlock.gif   
53ContractedSubBlock.gifExpandedSubBlockStart.gif                Get DebugID;#region Get DebugID;
54InBlock.gif                targetCommand.CommandText = "select SYS.DBMS_DEBUG.Initialize(null,0) from dual";
55InBlock.gif                debugID = targetCommand.ExecuteScalar().ToString();
56ExpandedSubBlockEnd.gif                #endregion
  
57InBlock.gif                targetCommand.CommandText = "begin SYS.DBMS_DEBUG.Debug_on(true,false); end;";                            
58InBlock.gif                targetCommand.ExecuteNonQuery ();
59ExpandedBlockEnd.gif            }

60 None.gif             this .executeException  =   null ;
61 None.gif             // if(this.targetThread == null)
62 None.gif             // {
63 None.gif                 targetThread  =   new  System.Threading.Thread( new  System.Threading.ThreadStart( this .Execute));
64 None.gif             // }
65 None.gif             
66 None.gif            targetThread.Start();            
67 None.gif            System.Threading.Thread.Sleep( 500 );    
68 None.gif             if ( this .Synchronize())
69 ExpandedBlockStart.gifContractedBlock.gif             dot.gif {
70InBlock.gif                this.Debug(BreakFlag.AnyCall);    
71InBlock.gif                this.btnStartDebug.Enabled = false;
72InBlock.gif                this.mStepInto.Enabled = true;
73InBlock.gif                this.mStepOver.Enabled = true;
74InBlock.gif                this.mRun.Enabled = true;                
75ExpandedBlockEnd.gif            }

76 None.gif             else
77 ExpandedBlockStart.gifContractedBlock.gif             dot.gif {
78InBlock.gif                this.executeException = null;
79InBlock.gif                this.IsDebuging = false;
80InBlock.gif                this.MSQL.Document.ReadOnly = false;
81InBlock.gif                this.btnStartDebug.Enabled = true;
82InBlock.gif                this.mStepInto.Enabled = false;
83InBlock.gif                this.mStepOver.Enabled = false;
84InBlock.gif                this.mRun.Enabled = false;
85InBlock.gif                if(this.ObjectName != null && this.ObjectName != "")
86ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{                
87InBlock.gif                    this.btnConfigure.Enabled = true;
88ExpandedSubBlockEnd.gif                }
                
89ExpandedBlockEnd.gif            }
            
90 None.gif        }
91 None.gif



与目标会话同步的代码:
None.gif private   bool  Synchronize()
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
if(this.targetThread.ThreadState == System.Threading.ThreadState.Stopped && this.executeException != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                ExceptionDialog.Show(
this.executeException.Message,MessageboxTitle.Title.Error,this.executeException);
InBlock.gif                
return false;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
string strSQL = "declare \n" +
InBlock.gif                
"    running_info sys.dbms_debug.runtime_info; \n" +
InBlock.gif                
"    seconds BINARY_INTEGER;" +
InBlock.gif                
"begin \n" +
InBlock.gif                
"     seconds := SYS.DBMS_DEBUG.SET_TIMEOUT(5*60); \n" +
InBlock.gif                
"     SYS.DBMS_DEBUG.ATTACH_SESSION(:debugid,0); \n" + 
InBlock.gif                
"    :sync_result := SYS.DBMS_DEBUG.SYNCHRONIZE(run_info => running_info, \n" +
InBlock.gif                
"                    info_requested => SYS.DBMS_DEBUG.info_getStackDepth + \n" +
InBlock.gif                
"                                     SYS.DBMS_DEBUG.info_getLineInfo + \n" +
InBlock.gif                
"                                        SYS.DBMS_DEBUG.info_getBreakpoint); \n" +
InBlock.gif                
"    seconds := SYS.DBMS_DEBUG.SET_TIMEOUT(3600); \n" +
InBlock.gif                
"end;";
InBlock.gif            
this.debugCommand.Parameters.Clear();
InBlock.gif            
this.debugCommand.CommandText = strSQL;
InBlock.gif            OracleParameter pdebugid 
= this.debugCommand.Parameters.Add("debugid",OracleType.VarChar,20);
InBlock.gif            pdebugid.Value 
= this.debugID;
InBlock.gif            OracleParameter psync_result 
= this.debugCommand.Parameters.Add("sync_result",OracleType.Int32);
InBlock.gif            psync_result.Direction 
= ParameterDirection.Output;
InBlock.gif            
this.debugCommand.ExecuteNonQuery();
InBlock.gif            
int p = int.Parse(psync_result.Value.ToString());
InBlock.gif            ErrorCode errorCode 
= (ErrorCode)p;
InBlock.gif            
return errorCode == ErrorCode.success;
ExpandedBlockEnd.gif        }


单步调试的代码:

 1 None.gif private  ErrorCode Continue( out  RuntimeInfo runtimeInfo,BreakFlag breakFlag)
 2 ExpandedBlockStart.gifContractedBlock.gif         dot.gif {    
 3InBlock.gif            runtimeInfo = new RuntimeInfo();
 4InBlock.gif            string strSQL=    "declare \n " +
 5InBlock.gif                "    running_info sys.dbms_debug.runtime_info; \n" +                            
 6InBlock.gif                "begin \n" + 
 7InBlock.gif                "    :cont_result := sys.dbms_debug.continue(run_info =>running_info,\n" +
 8InBlock.gif                "                                            breakflags =>:breakflag,\n" +
 9InBlock.gif                "                                            info_requested =>sys.dbms_debug.info_getStackDepth + \n" +
10InBlock.gif                "                                            sys.dbms_debug.info_getLineInfo + sys.dbms_debug.info_getBreakpoint);" +
11InBlock.gif                "    :Terminated := running_info.Terminated;\n" +
12InBlock.gif                "    :Line := running_info.Line#; \n" +
13InBlock.gif                "    :Reason := running_info.Reason;\n" +
14InBlock.gif                "    :BreakPoint := running_info.BreakPoint;\n" +
15InBlock.gif                "    :Oer := running_info.Oer;\n" +
16InBlock.gif                "    :StackDepth := running_info.StackDepth;\n" +
17InBlock.gif                "    :DBLink := running_info.Program.DBLink;\n" +
18InBlock.gif                "    :EntrypointName := running_info.Program.EntrypointName;\n" + 
19InBlock.gif                "    :Name := running_info.Program.Name;\n" +
20InBlock.gif                "    :NameSpace := running_info.Program.NameSpace;\n" +
21InBlock.gif                "    :Owner := running_info.Program.Owner;\n" +
22InBlock.gif                "    :UnitType := running_info.Program.LibunitType;\n" +
23InBlock.gif                "end;";
24InBlock.gif            this.debugCommand.Parameters.Clear();
25InBlock.gif            
26InBlock.gif            OracleParameter pIn = this.debugCommand.Parameters.Add("breakflag",OracleType.Int32);
27InBlock.gif            pIn.Value = breakFlag;
28InBlock.gif
29InBlock.gif            OracleParameter pOut = this.debugCommand.Parameters.Add("Terminated",OracleType.Int32);
30InBlock.gif            pOut.Direction = ParameterDirection.Output;
31InBlock.gif            
32InBlock.gif            pOut = this.debugCommand.Parameters.Add("Line",OracleType.Int32);
33InBlock.gif            pOut.Direction = ParameterDirection.Output;
34InBlock.gif
35InBlock.gif            pOut = this.debugCommand.Parameters.Add("Reason",OracleType.Int32);
36InBlock.gif            pOut.Direction = ParameterDirection.Output;
37InBlock.gif
38InBlock.gif            pOut = this.debugCommand.Parameters.Add("BreakPoint",OracleType.Int32);
39InBlock.gif            pOut.Direction = ParameterDirection.Output;
40InBlock.gif            
41InBlock.gif            pOut = this.debugCommand.Parameters.Add("Oer",OracleType.Int32);
42InBlock.gif            pOut.Direction = ParameterDirection.Output;
43InBlock.gif
44InBlock.gif            pOut = this.debugCommand.Parameters.Add("StackDepth",OracleType.Int32);
45InBlock.gif            pOut.Direction = ParameterDirection.Output;
46InBlock.gif            
47InBlock.gif            pOut = this.debugCommand.Parameters.Add("DBLink",OracleType.VarChar,20);
48InBlock.gif            pOut.Direction = ParameterDirection.Output;
49InBlock.gif            
50InBlock.gif            pOut = this.debugCommand.Parameters.Add("EntrypointName",OracleType.VarChar,20);
51InBlock.gif            pOut.Direction = ParameterDirection.Output;
52InBlock.gif            
53InBlock.gif            pOut = this.debugCommand.Parameters.Add("Name",OracleType.VarChar,20);
54InBlock.gif            pOut.Direction = ParameterDirection.Output;
55InBlock.gif            
56InBlock.gif            pOut = this.debugCommand.Parameters.Add("NameSpace",OracleType.Int32);
57InBlock.gif            pOut.Direction = ParameterDirection.Output;
58InBlock.gif
59InBlock.gif            pOut = this.debugCommand.Parameters.Add("Owner",OracleType.VarChar,20);
60InBlock.gif            pOut.Direction = ParameterDirection.Output;
61InBlock.gif            
62InBlock.gif
63InBlock.gif            pOut = this.debugCommand.Parameters.Add("UnitType",OracleType.Int32);
64InBlock.gif            pOut.Direction = ParameterDirection.Output;
65InBlock.gif            
66InBlock.gif            pOut = this.debugCommand.Parameters.Add("cont_result",OracleType.Int32);
67InBlock.gif            pOut.Direction = ParameterDirection.Output;
68InBlock.gif
69InBlock.gif            this.debugCommand.CommandText = strSQL;
70InBlock.gif            this.debugCommand.ExecuteNonQuery();
71InBlock.gif            
72InBlock.gif            pOut = this.debugCommand.Parameters["cont_result"];
73InBlock.gif            int p = int.Parse(pOut.Value.ToString());
74InBlock.gif            ErrorCode errorCode = (ErrorCode)p;
75InBlock.gif            
76InBlock.gif            runtimeInfo.Terminated = 0;
77InBlock.gif            if(errorCode == ErrorCode.success)
78ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
79InBlock.gif                runtimeInfo.Terminated = GetValueFromParameters(this.debugCommand.Parameters,"Terminated",-1);
80InBlock.gif                runtimeInfo.Line = GetValueFromParameters(this.debugCommand.Parameters,"Line",-1);
81InBlock.gif                runtimeInfo.Reason = (ReasonFlag)GetValueFromParameters(this.debugCommand.Parameters,"Reason",0);                
82InBlock.gif                runtimeInfo.Breakpoint = GetValueFromParameters(this.debugCommand.Parameters,"Breakpoint",-1);
83InBlock.gif                runtimeInfo.Oer = GetValueFromParameters(this.debugCommand.Parameters,"Oer",-1);
84InBlock.gif                runtimeInfo.StackDepth = GetValueFromParameters(this.debugCommand.Parameters,"StackDepth",-1);                
85InBlock.gif                runtimeInfo.Program.Dblink = GetValueFromParameters(this.debugCommand.Parameters,"DBLink","");
86InBlock.gif                runtimeInfo.Program.EntrypointName = GetValueFromParameters(this.debugCommand.Parameters,"EntrypointName","");
87InBlock.gif                runtimeInfo.Program.Line = runtimeInfo.Line;
88InBlock.gif                runtimeInfo.Program.Name = GetValueFromParameters(this.debugCommand.Parameters,"Name","");
89InBlock.gif                runtimeInfo.Program.Namespace = (NameSpace)GetValueFromParameters(this.debugCommand.Parameters,"NameSpace",127);
90InBlock.gif                runtimeInfo.Program.Owner = GetValueFromParameters(this.debugCommand.Parameters,"Owner","");
91InBlock.gif                runtimeInfo.Program.UnitType =(LibunitType)GetValueFromParameters(this.debugCommand.Parameters,"UnitType",-1);
92ExpandedSubBlockEnd.gif            }

93InBlock.gif            return errorCode;
94ExpandedBlockEnd.gif        }

处理单步调试结果的代码:
 1 None.gif private   void  Debug(BreakFlag breakFlag)
 2 ExpandedBlockStart.gifContractedBlock.gif         dot.gif {
 3InBlock.gif            RuntimeInfo runtimeInfo;             
 4InBlock.gif            this.Continue(out runtimeInfo,breakFlag);
 5InBlock.gif            //this.MString.ActiveTextAreaControl.TextArea.            
 6InBlock.gif            if(runtimeInfo.Reason == ReasonFlag.KernlExit || this.targetThread.ThreadState == System.Threading.ThreadState.Stopped)
 7ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 8InBlock.gif                this.DetachSession();    
 9InBlock.gif                this.MSQL.ActiveTextAreaControl.SelectionManager.ClearSelection();
10InBlock.gif                System.Threading.Thread.Sleep(500);
11InBlock.gif                if(this.executeException != null)
12ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
13InBlock.gif                    ExceptionDialog.Show(this.executeException.Message,MessageboxTitle.Title.Error,this.executeException);
14ExpandedSubBlockEnd.gif                }
                
15InBlock.gif                else
16ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
17InBlock.gif                    DisplayOutParameter();
18ExpandedSubBlockEnd.gif                }

19InBlock.gif//                if(this.targetThread.ThreadState != System.Threading.ThreadState.Stopped)
20InBlock.gif//                    this.AutoDebug();
21InBlock.gif                this.IsDebuging = false;
22InBlock.gif                if(this.ObjectName != null && this.ObjectName != "")
23ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{                
24InBlock.gif                    this.btnConfigure.Enabled = true;
25ExpandedSubBlockEnd.gif                }

26InBlock.gif                this.richTextBox1.Text = "";
27InBlock.gif                this.MSQL.Document.ReadOnly = false;
28InBlock.gif                this.mRun.Enabled = false;
29InBlock.gif                this.mStepInto.Enabled = false;
30InBlock.gif                this.mStepOver.Enabled = false;
31InBlock.gif                this.btnStartDebug.Enabled = true;
32InBlock.gif                if(currentDebugSQLEditor != null && currentDebugMarker != null)
33ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
34InBlock.gif                    currentDebugSQLEditor.Document.MarkerStrategy.TextMarker.Remove(currentDebugMarker);
35InBlock.gif                    currentDebugSQLEditor.Refresh();
36ExpandedSubBlockEnd.gif                }

37ExpandedSubBlockEnd.gif            }

38InBlock.gif            else if(runtimeInfo.Program.Name == "" && runtimeInfo.Line > 0)
39ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
40InBlock.gif                this.tabSource.SelectedTab = this.tabSource.TabPages[0];
41InBlock.gif                Highlight(this.tabSource.TabPages[0],runtimeInfo.Line);
42InBlock.gif                DisplayAllVarValue();
43InBlock.gif                GetBackTrace();
44ExpandedSubBlockEnd.gif            }

45InBlock.gif            else if(runtimeInfo.Program.Name != "" && runtimeInfo.Line > 0)
46ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
47InBlock.gif                int x =0;
48InBlock.gif                x ++;
49InBlock.gif                string objectName  = runtimeInfo.Program.Owner + "." + runtimeInfo.Program.Name;
50InBlock.gif                Crownwood.Magic.Controls.TabPage sourcePage = this.GetTabPage(runtimeInfo);
51InBlock.gif                //if(runtimeInfo.Program.Namespace == NameSpace.Pkg_Body 
52InBlock.gif                if(sourcePage == null)
53ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
54InBlock.gif                    sourcePage = this.GenerateTabPage(runtimeInfo);
55InBlock.gif                    
56ExpandedSubBlockEnd.gif                }

57InBlock.gif                if(sourcePage != null)
58ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
59InBlock.gif                    this.tabSource.SelectedTab = sourcePage;
60InBlock.gif                    Highlight(sourcePage,runtimeInfo.Line);
61ExpandedSubBlockEnd.gif                }

62InBlock.gif                DisplayAllVarValue();
63InBlock.gif                GetBackTrace();
64ExpandedSubBlockEnd.gif            }

65ExpandedBlockEnd.gif        }

所有的源代码:
/Files/SharkXu/OracleDebug.zip

Oracle 调试功能我已经融合进了我的 Shark DB Expert









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值