應用系統如何分析和獲取SQL語句的執行代碼

大部分開發人員都有這樣一個需求,在程序鏈接數據庫執行時,有時須要獲取具體的執行語句,以便進行相關分析,此次我向你們介紹一下通用權限管理系統提供的SQL語句執行跟蹤記錄,直接先看看代碼吧:(這個功能我也是在看底層代碼時發現的)sql

namespace DotNet.Utilities
{
    /// <summary>
    /// SQLTrace
    /// 記錄SQL執行 Global 中設置 BaseSystemInfo.LogSQL=true 能夠開啓跟蹤記錄
    /// 
    /// 
    /// 修改紀錄
    /// 
    ///        2016.01.12 版本:1.0    SongBiao
    ///    
    /// <author>
    ///        <name>SongBiao</name>
    ///        <date>2016.01.12</date>
    /// </author> 
    /// </summary>
    public class SQLTrace
    {
        private static string FileName = "SQLTrace.txt";

        #region public static void WriteLog(string commandText,IDbDataParameter[] dbParameters = null,  string fileName = null) 寫入sql查詢句日誌
        /// <summary>
        /// 寫入sql查詢句日誌
        /// </summary>
        /// <param name="commandText">異常</param>
        /// <param name="dbParameters"></param>
        /// <param name="fileName">文件名</param>
        public static void WriteLog(string commandText, IDbDataParameter[] dbParameters = null, string fileName = null)
        {
            // 系統裏應該能夠配置是否記錄異常現象
            if (!BaseSystemInfo.LogSQL)
            {
                return;
            }
            if (string.IsNullOrEmpty(fileName))
            {
                fileName = DateTime.Now.ToString(BaseSystemInfo.DateFormat) + " _ " + FileName;
            }
            string message = string.Empty;
            message = DateTime.Now.ToString(BaseSystemInfo.DateTimeFormat) + System.Environment.NewLine + "commandText內容" + System.Environment.NewLine + commandText;
            if (dbParameters != null)
            {
                StringBuilder sb = new StringBuilder();
                foreach (var parameter in dbParameters)
                {
                    sb.AppendLine(parameter.ParameterName + "=" + parameter.Value);
                }
                message += System.Environment.NewLine + "dbParameters內容" + System.Environment.NewLine + sb.ToString();
            }
            // 將異常信息寫入本地文件中
            string logDirectory = BaseSystemInfo.StartupPath + @"\Log\Query";
            if (!System.IO.Directory.Exists(logDirectory))
            {
                System.IO.Directory.CreateDirectory(logDirectory);
            }
            string writerFileName = logDirectory + "\\" + fileName;
            FileUtil.WriteMessage(message, writerFileName);
        }
        #endregion
    }
}

方法比較簡單,傳入參數化的SQL語句及參數數組,就能夠在文件中記錄每次具體的操做語句。以下圖:(訪問的是MySQL數據庫)數據庫

【通用權限管理系統中獲取某個用戶具備的權限(數組)的語句,記錄了CommandText和dbParameters兩部分,拼接一下就能夠執行了】數組

你們能夠參照這個,寫出對應的方法記錄本身程序訪問數據庫的語句。ui

咱們來看看在通用權限底層是如何調用這個功能的:this

一、在應用程序的Global中加入如下語句,開啓日誌記錄及存儲位置設置spa

            BaseSystemInfo.StartupPath = HttpContext.Current.Server.MapPath("~/");
            BaseSystemInfo.LogSQL = true;

以下圖日誌

 

二、調用的一個地方參考code

        #region public virtual DataSet Fill(DataSet dataSet, string commandText, string tableName, IDbDataParameter[] dbParameters, CommandType commandType) 填充數據權限
        /// <summary>
        /// 填充數據權限
        /// </summary>
        /// <param name="dataSet">數據權限</param>
        /// <param name="commandType">命令分類</param>
        /// <param name="commandText">sql查詢</param>
        /// <param name="tableName">填充表</param>
        /// <param name="dbParameters">參數集</param>
        /// <returns>數據權限</returns>
        public virtual DataSet Fill(DataSet dataSet, string commandText, string tableName, IDbDataParameter[] dbParameters, CommandType commandType)
        {
            // 自動打開
            if (this.DbConnection == null)
            {
                this.Open();
                this.MustCloseConnection = true;
            }
            else if (this.DbConnection.State == ConnectionState.Closed)
            {
                this.Open();
                this.MustCloseConnection = true;
            }

            using (this.dbCommand = this.DbConnection.CreateCommand())
            {
                this.dbCommand.CommandTimeout = this.DbConnection.ConnectionTimeout;
                this.dbCommand.CommandText = commandText;
                this.dbCommand.CommandType = commandType;
                if (this.dbTransaction != null)
                {
                    this.dbCommand.Transaction = this.dbTransaction;
                }

                if ((dbParameters != null) && (dbParameters.Length > 0))
                {
                    for (int i = 0; i < dbParameters.Length; i++)
                    {
                        if (dbParameters[i] != null)
                        {
                            this.dbCommand.Parameters.Add(((ICloneable)dbParameters[i]).Clone());
                        }
                    }

                }

                this.dbDataAdapter = this.GetInstance().CreateDataAdapter();
                this.dbDataAdapter.SelectCommand = this.dbCommand;
                this.dbDataAdapter.Fill(dataSet, tableName);

                SetBackParamValue(dbParameters);

                if (this.MustCloseConnection)
                {
                    this.Close();
                }
                else
                {
                    this.dbDataAdapter.SelectCommand.Parameters.Clear();
                }
            }

            // 記錄日誌
            SQLTrace.WriteLog(commandText, dbParameters);

            return dataSet;
        }
        #endregion

 

這個功能好好利用,對於分析系統的SQL執行是很是方便的。orm

相關文章
相關標籤/搜索