zoukankan      html  css  js  c++  java
  • 用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;

    请看下面的流程图关于目标会话/调试会话需要执行的动作及其相互关系:

    启动调试的代码:
     1private void StartDebug()
     2        {
     3            
    13
    14            initialize target session and command 
    30
    31            initialize debug session and command
    40   
    41            prepare 
    52   
    53                Get DebugID;  
    57                targetCommand.CommandText = "begin SYS.DBMS_DEBUG.Debug_on(true,false); end;";                            
    58                targetCommand.ExecuteNonQuery ();
    59            }

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

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



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

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


    单步调试的代码:

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

    93            return errorCode;
    94        }

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

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

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

    37            }

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

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

    57                if(sourcePage != null)
    58                {
    59                    this.tabSource.SelectedTab = sourcePage;
    60                    Highlight(sourcePage,runtimeInfo.Line);
    61                }

    62                DisplayAllVarValue();
    63                GetBackTrace();
    64            }

    65        }

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

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









  • 相关阅读:
    python3爬虫--反爬虫应对机制
    mongodb与mysql区别(超详细)
    cookie和session运行机制、区别
    flask轻量级框架入门
    python自定义元类metaclass,约束子类
    MongoDB ObjectId类型 序列化问题
    【python 内置模块】 返回一个规定长度的随机字符串
    使用PyMongo有多重,使用MongoClientwith的实例时必须小心 fork()
    MySQL 服务正在启动 . MySQL 服务无法启动。 服务没有报告任何错误。
    分布式文件系统架构HDFS、FastDFS、Haystack
  • 原文地址:https://www.cnblogs.com/SharkXu/p/OracleDebug.html
Copyright © 2011-2022 走看看